Commit 9da0a538 by jiang'yun

修改

parent 0a22694f
import request from "@/utils/request"; import request from "@/utils/request";
// 查询录井整米数据列表 // 查询录井整米数据列表
export function listLjSssjSd(query) { export function listLjSssjSd(query) {
return request({ return request({
url: "/system/ljSssjSd/list", url: "/system/ljSssjSd/list",
method: "get", method: "get",
params: query, params: query,
}); });
} }
// 查询录井整米数据详细 // 查询录井整米数据详细
export function getLjSssjSd(id) { export function getLjSssjSd(id) {
return request({ return request({
url: "/system/ljSssjSd/" + id, url: "/system/ljSssjSd/" + id,
method: "get", method: "get",
}); });
} }
// 新增录井整米数据 // 新增录井整米数据
export function addLjSssjSd(data) { export function addLjSssjSd(data) {
return request({ return request({
url: "/system/ljSssjSd", url: "/system/ljSssjSd",
method: "post", method: "post",
data: data, data: data,
}); });
} }
// 修改录井整米数据 // 修改录井整米数据
export function updateLjSssjSd(data) { export function updateLjSssjSd(data) {
return request({ return request({
url: "/system/ljSssjSd", url: "/system/ljSssjSd",
method: "put", method: "put",
data: data, data: data,
}); });
} }
// 删除录井整米数据 // 删除录井整米数据
export function delLjSssjSd(id) { export function delLjSssjSd(id) {
return request({ return request({
url: "/system/ljSssjSd/" + id, url: "/system/ljSssjSd/" + id,
method: "delete", method: "delete",
}); });
} }
// 查询录井整米数据列表
export function getLjzmsj(query) {
return request({
url: "/system/ljSssjSd/getLjzmsj",
method: "get",
params: query,
});
}
<template> <template>
<div class="drilling-chart-container"> <div class="drilling-chart-container">
<div class="chart-wrapper"> <div>
<el-button type="primary" icon="el-icon-download" size="small" class="export-btn" @click="exportChart" <span class="well-label" style="margin-left: 10px">开次:</span>
:disabled="!myChart"> <el-select v-model="kc" style="width: 100px" size="mini" clearable placeholder="请选择">
导出图片 <el-option
</el-button> v-for="item in kcData"
<div id="drillingEfficiencyChartdj" class="chart"></div> :key="item.value"
</div> :label="item.label"
<!-- <div class="optimal-values"> :value="item.value">
<div class="optimal-item"> </el-option>
<span class="label">机速最优:</span> </el-select>
<span class="value">{{ (chartData && chartData.jxzszy) || '--' }}</span> <span class="well-label" style="margin-left: 10px">钻头尺寸:</span>
</div> <el-input v-model="ztccs" style="width: 100px" clearable size="mini"></el-input>
<div class="optimal-item"> <el-button type="primary" style="margin-left: 10px" size="mini" @click="getList">查询</el-button>
<span class="label">进尺最优:</span> <el-button type="primary" icon="el-icon-download" size="small" @click="exportChart"
<span class="value">{{ (chartData && chartData.jczy) || '--' }}</span> :disabled="!myChart"></el-button>
</div>
<div class="optimal-item">
<span class="label">综合最优:</span>
<span class="value">{{ (chartData && chartData.zhzy) || '--' }}</span>
</div>
</div> -->
<el-table v-if="chartData && chartData.zyzt && chartData.zyzt.length > 0" :data="chartData.zyzt" border stripe
class="data-table">
<el-table-column label="井号" align="center" prop="jh" min-width="120" show-overflow-tooltip />
<el-table-column label="钻头尺寸mm" align="center" prop="ztcc" min-width="120" show-overflow-tooltip />
<el-table-column label="钻头型号" align="center" prop="ztxh" min-width="150" show-overflow-tooltip />
<el-table-column label="优选类型" align="center" prop="yxlx" min-width="120" show-overflow-tooltip />
</el-table>
</div> </div>
<div class="chart-wrapper">
<div id="drillingEfficiencyChartdj" class="chart"></div>
</div>
<el-table v-if="chartData && chartData.zyzt && chartData.zyzt.length > 0" :data="chartData.zyzt" border stripe
class="data-table">
<el-table-column label="井号" align="center" prop="jh" min-width="120" show-overflow-tooltip/>
<el-table-column label="钻头尺寸mm" align="center" prop="ztcc" min-width="120" show-overflow-tooltip/>
<el-table-column label="钻头型号" align="center" prop="ztxh" min-width="150" show-overflow-tooltip/>
<el-table-column label="优选类型" align="center" prop="yxlx" min-width="120" show-overflow-tooltip/>
</el-table>
</div>
</template> </template>
<script> <script>
import * as echarts from 'echarts'; import * as echarts from 'echarts';
import { getdjqxt } from '@/api/optimization/initialization'; import {getdjqxt} from '@/api/optimization/initialization';
export default { export default {
props: { props: {
jh: { jh: {
type: String, type: String,
required: true, required: true,
},
jhs: {
type: String,
required: true,
},
id: {
type: String,
required: true,
}
}, },
data() { jhs: {
return { type: String,
chartData: null, required: true,
myChart: null,
resizeHandler: null
};
}, },
mounted() { id: {
// 不在挂载时自动请求数据,等待父组件触发 loadData() type: String,
this.$once('hook:beforeDestroy', this.cleanup); required: true,
}, },
methods: { kcjs: {
// 供父组件调用 type: String,
loadData() { required: true,
this.getList(); },
}, ztccsjs: {
getList() { type: String,
const params = { required: true,
zbid: this.id, }
jhs: `${this.jh},${this.jhs}` },
}; data() {
getdjqxt(params) return {
.then(res => { chartData: null,
console.log('接口返回数据:', res); myChart: null,
this.chartData = res; resizeHandler: null,
this.initChart(); kc: '',
}) ztccs: '',
.catch(error => { kcData: [
console.error('接口请求失败:', error); {
this.chartData = null; label: '1',
this.initChart(); value: '1',
}); }, {
label: '2',
value: '2',
}, {
label: '3',
value: '3',
}, {
label: '4',
value: '4',
}, {
label: '5',
value: '5',
}, },
]
};
},
created() {
this.kc=this.kcjs
this.ztccs=this.ztccsjs
},
mounted() {
// 不在挂载时自动请求数据,等待父组件触发 loadData()
this.$once('hook:beforeDestroy', this.cleanup);
},
initChart() { methods: {
if (!this.chartData) { // 供父组件调用
const chartDom = document.getElementById('drillingEfficiencyChartdj'); loadData() {
if (chartDom && this.myChart) { this.getList();
this.myChart.clear(); },
} getList() {
return; const params = {
} zbid: this.id,
const chartDom = document.getElementById('drillingEfficiencyChartdj'); jhs: `${this.jh},${this.jhs}`,
if (!chartDom) { kc:this.kc,
console.error('未找到图表容器'); ztccs:this.ztccs
return; };
} getdjqxt(params)
if (chartDom.offsetWidth === 0 || chartDom.offsetHeight === 0) { .then(res => {
console.log('容器尺寸为0,200ms后重试'); console.log('接口返回数据:', res);
setTimeout(() => this.initChart(), 200); this.chartData = res;
return; this.initChart();
} })
if (this.myChart) { .catch(error => {
this.myChart.dispose(); console.error('接口请求失败:', error);
} this.chartData = null;
this.myChart = echarts.init(chartDom); this.initChart();
// 解析接口数据(确保折线数据格式正确) });
const { axisRange, scatterData, targetLineData, crosshair } = this.chartData; },
// 数据顺序:[speed, depth, drillType, jh, cc]
const scatter = scatterData.map(item => [item.speed, item.depth, item.drillType, item.jh, item.cc]);
// 折线数据必须为数组格式:[[钻速, 进尺], ...]
const targetLine = targetLineData.map(item => [item.speed, item.depth]);
const drillTypes = [...new Set(scatterData.map(item => item.drillType))];
// 定义颜色数组,为不同钻头型号分配不同颜色
const colorPalette = [
'#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de',
'#3ba272', '#fc8452', '#9a60b4', '#ea7ccc', '#ff9f7f',
'#ffdb5c', '#c4ccd3', '#4ea397', '#22c3aa', '#7bd9a5',
'#d0648a', '#f0a1a8', '#f7c369', '#4d79a4', '#e15b64'
];
// 十字线及中心点配置
const crosshairLines = [];
const crosshairCenter = [];
if (crosshair) {
crosshairLines.push({
name: '十字线',
type: 'line',
data: [[crosshair.y - 10, crosshair.x], [crosshair.y + 10, crosshair.x]],
lineStyle: { color: 'black', width: 1, type: 'dashed' },
symbol: 'none',
tooltip: { show: false } // 十字线不显示tooltip
});
crosshairLines.push({
name: '十字线',
type: 'line',
data: [[crosshair.y, crosshair.x - 500], [crosshair.y, crosshair.x + 500]],
lineStyle: { color: 'black', width: 1, type: 'dashed' },
symbol: 'none',
tooltip: { show: false } // 十字线不显示tooltip
});
crosshairCenter.push({
name: '十字线中心',
type: 'scatter',
data: [[crosshair.y, crosshair.x]],
symbolSize: 12,
itemStyle: { color: 'orange', borderColor: '#fff', borderWidth: 2 }
});
}
// 图表配置项(核心:坐标轴触发,确保折线悬浮显示) initChart() {
const option = { if (!this.chartData) {
title: { text: '钻头钻进能效分析', left: 'center' }, const chartDom = document.getElementById('drillingEfficiencyChartdj');
tooltip: { if (chartDom && this.myChart) {
trigger: 'axis', // 基于坐标轴触发(不依赖数据点) this.myChart.clear();
axisPointer: { }
type: 'line', // 显示轴线指示器,辅助定位折线数据点 return;
snap: true // 强制吸附到最近的折线数据点 }
}, const chartDom = document.getElementById('drillingEfficiencyChartdj');
formatter: (params) => { if (!chartDom) {
// 遍历所有系列数据,找到折线图的信息 console.error('未找到图表容器');
const lineData = params.find(p => p.seriesName === '优化曲线'); return;
const scatterData = params.find(p => drillTypes.includes(p.seriesName)); }
const centerData = params.find(p => p.seriesName === '十字线中心'); if (chartDom.offsetWidth === 0 || chartDom.offsetHeight === 0) {
console.log('容器尺寸为0,200ms后重试');
setTimeout(() => this.initChart(), 200);
return;
}
if (this.myChart) {
this.myChart.dispose();
}
this.myChart = echarts.init(chartDom);
// 解析接口数据(确保折线数据格式正确)
const {axisRange, scatterData, targetLineData, crosshair} = this.chartData;
// 数据顺序:[speed, depth, drillType, jh, cc]
const scatter = scatterData.map(item => [item.speed, item.depth, item.drillType, item.jh, item.cc]);
// 折线数据必须为数组格式:[[钻速, 进尺], ...]
const targetLine = targetLineData.map(item => [item.speed, item.depth]);
const drillTypes = [...new Set(scatterData.map(item => item.drillType))];
// 定义颜色数组,为不同钻头型号分配不同颜色
const colorPalette = [
'#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de',
'#3ba272', '#fc8452', '#9a60b4', '#ea7ccc', '#ff9f7f',
'#ffdb5c', '#c4ccd3', '#4ea397', '#22c3aa', '#7bd9a5',
'#d0648a', '#f0a1a8', '#f7c369', '#4d79a4', '#e15b64'
];
// 十字线及中心点配置
const crosshairLines = [];
const crosshairCenter = [];
if (crosshair) {
crosshairLines.push({
name: '十字线',
type: 'line',
data: [[crosshair.y - 10, crosshair.x], [crosshair.y + 10, crosshair.x]],
lineStyle: {color: 'black', width: 1, type: 'dashed'},
symbol: 'none',
tooltip: {show: false} // 十字线不显示tooltip
});
crosshairLines.push({
name: '十字线',
type: 'line',
data: [[crosshair.y, crosshair.x - 500], [crosshair.y, crosshair.x + 500]],
lineStyle: {color: 'black', width: 1, type: 'dashed'},
symbol: 'none',
tooltip: {show: false} // 十字线不显示tooltip
});
crosshairCenter.push({
name: '十字线中心',
type: 'scatter',
data: [[crosshair.y, crosshair.x]],
symbolSize: 12,
itemStyle: {color: 'orange', borderColor: '#fff', borderWidth: 2}
});
}
let result = ''; // 图表配置项(核心:坐标轴触发,确保折线悬浮显示)
// 折线图数据(必显) const option = {
// if (lineData) { title: {text: '钻头钻进能效分析', left: 'center'},
// result += `优化曲线<br>钻速:${lineData.data[0]} m/h<br>进尺:${lineData.data[1]}<br>`; tooltip: {
// } trigger: 'axis', // 基于坐标轴触发(不依赖数据点)
// 散点数据(如果鼠标在散点上) axisPointer: {
if (scatterData) { type: 'line', // 显示轴线指示器,辅助定位折线数据点
const [speed, depth, drillType, jh, cc] = scatterData.data; snap: true // 强制吸附到最近的折线数据点
result += `井号:${jh}<br>机械钻速m/h${speed} m/h<br>进尺:${depth}<br>钻头型号:${drillType}<br>钻头尺寸:${cc}`; },
} formatter: (params) => {
// 中心点数据(如果鼠标在中心点上) // 遍历所有系列数据,找到折线图的信息
// if (centerData) { const lineData = params.find(p => p.seriesName === '优化曲线');
// result += `均值<br>钻速:${centerData.data[0]} m/h<br>进尺:${centerData.data[1]}<br>`; const scatterData = params.find(p => drillTypes.includes(p.seriesName));
// } const centerData = params.find(p => p.seriesName === '十字线中心');
return result;
} let result = '';
}, // 折线图数据(必显)
legend: { // if (lineData) {
data: ['优化曲线', '钻速均值', '进尺均值'], // result += `优化曲线<br>钻速:${lineData.data[0]} m/h<br>进尺:${lineData.data[1]}<br>`;
top: '10%', // }
right: '5%' // 散点数据(如果鼠标在散点上)
}, if (scatterData) {
grid: { const [speed, depth, drillType, jh, cc] = scatterData.data;
left: '2%', result += `井号:${jh}<br>机械钻速m/h${speed} m/h<br>进尺:${depth}<br>钻头型号:${drillType}<br>钻头尺寸:${cc}`;
right: '5%', }
top: '15%', // 中心点数据(如果鼠标在中心点上)
bottom: '10%', // if (centerData) {
containLabel: true // result += `均值<br>钻速:${centerData.data[0]} m/h<br>进尺:${centerData.data[1]}<br>`;
}, // }
xAxis: { return result;
name: '钻速 (m/h)', }
type: 'value', },
min: axisRange.xAxis.min, legend: {
max: axisRange.xAxis.max, data: ['优化曲线', '钻速均值', '进尺均值'],
// interval: axisRange.xAxis.interval, top: '10%',
axisLabel: { formatter: '{value} m/h' }, right: '5%'
nameLocation: 'center', },
nameGap: 50, grid: {
axisTick: { show: true }, left: '2%',
axisLine: { show: true } right: '5%',
}, top: '15%',
yAxis: { bottom: '10%',
name: '进尺m', containLabel: true
type: 'value', },
min: axisRange.yAxis.min, xAxis: {
// interval: axisRange.yAxis.interval, name: '钻速 (m/h)',
nameLocation: 'center', type: 'value',
nameGap: 40, min: axisRange.xAxis.min,
axisTick: { show: true }, max: axisRange.xAxis.max,
axisLine: { show: true } // interval: axisRange.xAxis.interval,
}, axisLabel: {formatter: '{value} m/h'},
series: [ nameLocation: 'center',
{ nameGap: 50,
name: '优化曲线', axisTick: {show: true},
type: 'line', axisLine: {show: true}
data: targetLine, // 确保数据正确 },
smooth: true, yAxis: {
// 彻底隐藏所有点(包括悬浮时) name: '进尺m',
symbol: 'none', type: 'value',
showSymbol: false, min: axisRange.yAxis.min,
emphasis: { showSymbol: false }, // interval: axisRange.yAxis.interval,
lineStyle: { color: 'red', width: 2 } nameLocation: 'center',
}, nameGap: 40,
{ axisTick: {show: true},
name: '钻速均值', axisLine: {show: true}
type: 'line', },
data: [[crosshair.x, axisRange.yAxis.min], [crosshair.x, axisRange.yAxis.max]], series: [
lineStyle: { color: '#9eca7f', width: 2, type: 'dashed' }, {
symbol: 'none', name: '优化曲线',
tooltip: { show: false } type: 'line',
}, data: targetLine, // 确保数据正确
{ smooth: true,
name: '进尺均值', // 彻底隐藏所有点(包括悬浮时)
type: 'line', symbol: 'none',
data: [[crosshair.x - 500, crosshair.y], [crosshair.x + 500, crosshair.y]], showSymbol: false,
lineStyle: { color: '#f2ca6b', width: 2 }, emphasis: {showSymbol: false},
symbol: 'none', lineStyle: {color: 'red', width: 2}
tooltip: { show: false } },
}, {
...crosshairLines, name: '钻速均值',
...crosshairCenter, type: 'line',
...drillTypes.map((type, index) => { data: [[crosshair.x, axisRange.yAxis.min], [crosshair.x, axisRange.yAxis.max]],
const color = colorPalette[index % colorPalette.length]; lineStyle: {color: '#9eca7f', width: 2, type: 'dashed'},
return { symbol: 'none',
name: type, tooltip: {show: false}
type: 'scatter', },
data: scatter.filter(item => item[2] === type), {
symbolSize: 12, name: '进尺均值',
itemStyle: { type: 'line',
color: color, data: [[crosshair.x - 500, crosshair.y], [crosshair.x + 500, crosshair.y]],
borderColor: color, lineStyle: {color: '#f2ca6b', width: 2},
borderWidth: 2, symbol: 'none',
shadowColor: color, tooltip: {show: false}
shadowBlur: 6 },
}, ...crosshairLines,
label: { ...crosshairCenter,
show: true, ...drillTypes.map((type, index) => {
position: 'top', const color = colorPalette[index % colorPalette.length];
formatter: type, return {
fontSize: 10, name: type,
color: '#333' type: 'scatter',
} data: scatter.filter(item => item[2] === type),
}; symbolSize: 12,
}) itemStyle: {
] color: color,
borderColor: color,
borderWidth: 2,
shadowColor: color,
shadowBlur: 6
},
label: {
show: true,
position: 'top',
formatter: type,
fontSize: 10,
color: '#333'
}
}; };
})
]
};
this.myChart.setOption(option); this.myChart.setOption(option);
this.resizeHandler = () => this.myChart.resize(); this.resizeHandler = () => this.myChart.resize();
window.addEventListener('resize', this.resizeHandler); window.addEventListener('resize', this.resizeHandler);
}, },
exportChart() { exportChart() {
if (!this.myChart) { if (!this.myChart) {
this.$message.warning('图表未初始化,无法导出'); this.$message.warning('图表未初始化,无法导出');
return; return;
} }
try { try {
// 获取图表的 base64 图片数据 // 获取图表的 base64 图片数据
const url = this.myChart.getDataURL({ const url = this.myChart.getDataURL({
type: 'png', type: 'png',
pixelRatio: 2, // 提高图片清晰度 pixelRatio: 2, // 提高图片清晰度
backgroundColor: '#fff' backgroundColor: '#fff'
}); });
// 创建下载链接 // 创建下载链接
const link = document.createElement('a'); const link = document.createElement('a');
link.href = url; link.href = url;
link.download = `钻头钻进能效分析_${this.jh}_${new Date().getTime()}.png`; link.download = `钻头钻进能效分析_${this.jh}_${new Date().getTime()}.png`;
document.body.appendChild(link); document.body.appendChild(link);
link.click(); link.click();
document.body.removeChild(link); document.body.removeChild(link);
this.$message.success('图片导出成功'); this.$message.success('图片导出成功');
} catch (error) { } catch (error) {
console.error('导出图片失败:', error); console.error('导出图片失败:', error);
this.$message.error('导出图片失败,请重试'); this.$message.error('导出图片失败,请重试');
} }
}, },
cleanup() { cleanup() {
if (this.myChart) { if (this.myChart) {
this.myChart.dispose(); this.myChart.dispose();
this.myChart = null; this.myChart = null;
} }
if (this.resizeHandler) { if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler); window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null; this.resizeHandler = null;
} }
}
} }
}
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.drilling-chart-container { .drilling-chart-container {
width: 100%; width: 100%;
height: 100%; height: 100%;
position: relative; position: relative;
padding: 20px; padding: 20px;
box-sizing: border-box; box-sizing: border-box;
} }
.optimal-values { .optimal-values {
position: absolute; position: absolute;
top: 10px; top: 10px;
left: 10px; left: 10px;
z-index: 10; z-index: 10;
background: linear-gradient(135deg, rgba(255, 255, 255, 0.95) 0%, rgba(248, 250, 252, 0.95) 100%); 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: 1px solid rgba(64, 158, 255, 0.15);
border-radius: 6px; border-radius: 6px;
padding: 6px 10px; 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); 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); backdrop-filter: blur(8px);
min-width: 200px; min-width: 200px;
max-width: 220px; max-width: 220px;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
word-wrap: break-word; word-wrap: break-word;
word-break: break-all; word-break: break-all;
white-space: normal; white-space: normal;
} }
.optimal-values:hover { .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); 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); transform: translateY(-2px);
border-color: rgba(64, 158, 255, 0.25); border-color: rgba(64, 158, 255, 0.25);
} }
.optimal-item { .optimal-item {
display: block; display: block;
margin-bottom: 4px; margin-bottom: 4px;
font-size: 13px; font-size: 13px;
padding: 2px 6px; padding: 2px 6px;
border-radius: 4px; border-radius: 4px;
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
position: relative; position: relative;
word-wrap: break-word; word-wrap: break-word;
word-break: break-all; word-break: break-all;
white-space: normal; white-space: normal;
text-align: left; text-align: left;
} }
.optimal-item:last-child { .optimal-item:last-child {
margin-bottom: 0; margin-bottom: 0;
} }
.optimal-item:hover { .optimal-item:hover {
background: linear-gradient(135deg, rgba(64, 158, 255, 0.08) 0%, rgba(103, 194, 58, 0.08) 100%); background: linear-gradient(135deg, rgba(64, 158, 255, 0.08) 0%, rgba(103, 194, 58, 0.08) 100%);
transform: translateX(2px); transform: translateX(2px);
box-shadow: 0 2px 8px rgba(64, 158, 255, 0.15); box-shadow: 0 2px 8px rgba(64, 158, 255, 0.15);
} }
.optimal-item::before { .optimal-item::before {
content: ''; content: '';
position: absolute; position: absolute;
left: 0; left: 0;
top: 50%; top: 50%;
transform: translateY(-50%); transform: translateY(-50%);
width: 3px; width: 3px;
height: 0; height: 0;
background: linear-gradient(135deg, #409eff 0%, #67c23a 100%); background: linear-gradient(135deg, #409eff 0%, #67c23a 100%);
border-radius: 2px; border-radius: 2px;
transition: height 0.2s ease; transition: height 0.2s ease;
} }
.optimal-item:hover::before { .optimal-item:hover::before {
height: 60%; height: 60%;
} }
.optimal-item .label { .optimal-item .label {
color: #5a5e66; color: #5a5e66;
font-weight: 500; font-weight: 500;
margin-right: 8px; margin-right: 8px;
font-size: 13px; font-size: 13px;
letter-spacing: 0.2px; letter-spacing: 0.2px;
opacity: 0.9; opacity: 0.9;
word-wrap: break-word; word-wrap: break-word;
word-break: break-all; word-break: break-all;
white-space: normal; white-space: normal;
display: inline; display: inline;
} }
.optimal-item .value { .optimal-item .value {
color: #2c3e50; color: #2c3e50;
font-weight: 700; font-weight: 700;
font-size: 13px; font-size: 13px;
background: linear-gradient(135deg, #409eff 0%, #67c23a 100%); background: linear-gradient(135deg, #409eff 0%, #67c23a 100%);
-webkit-background-clip: text; -webkit-background-clip: text;
-webkit-text-fill-color: transparent; -webkit-text-fill-color: transparent;
background-clip: text; background-clip: text;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
position: relative; position: relative;
word-wrap: break-word; word-wrap: break-word;
word-break: break-all; word-break: break-all;
white-space: normal; white-space: normal;
text-align: left; text-align: left;
display: inline; display: inline;
} }
.optimal-item .value::after { .optimal-item .value::after {
content: ''; content: '';
position: absolute; position: absolute;
bottom: -1px; bottom: -1px;
left: 0; left: 0;
width: 100%; width: 100%;
height: 1px; height: 1px;
background: linear-gradient(135deg, #409eff 0%, #67c23a 100%); background: linear-gradient(135deg, #409eff 0%, #67c23a 100%);
opacity: 0; opacity: 0;
transition: opacity 0.2s ease; transition: opacity 0.2s ease;
} }
.optimal-item:hover .value::after { .optimal-item:hover .value::after {
opacity: 0.3; opacity: 0.3;
} }
.chart-wrapper { .chart-wrapper {
position: relative; position: relative;
width: 100%; width: 100%;
height: calc(100vh - 220px); height: calc(100vh - 220px);
min-height: 600px; min-height: 600px;
} }
.chart { .chart {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.export-btn { .export-btn {
position: absolute; position: absolute;
top: 10px; top: 10px;
right: 10px; right: 10px;
z-index: 100; z-index: 100;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
} }
.data-table { .data-table {
width: 100%; width: 100%;
margin-top: 20px; margin-top: 20px;
} }
</style> </style>
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
<!-- 多井能效分析方案详情 --> <!-- 多井能效分析方案详情 -->
<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 ref="dataTableRef" :jh="queryParams.jh" :famc="queryParams.famc" :qk="queryParams.qk" <DataTable ref="dataTableRef" :jh="queryParams.jh" :famc="queryParams.famc" :qk="queryParams.qk"
:jhs="queryParams.jhs" /> :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" :id="queryParams.id" /> :jhs="queryParams.jhs" :id="queryParams.id" :kcjs="queryParams.kc" :ztccsjs="queryParams.ztccs" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="直方图形" name="histogramGraph"> <el-tab-pane label="钻头能效分析" name="histogramGraph">
<HistogramGraph ref="histogramGraphRef" :jh="queryParams.jh" :famc="queryParams.famc" <HistogramGraph ref="histogramGraphRef" :jh="queryParams.jh" :famc="queryParams.famc"
:qk="queryParams.qk" :jhs="queryParams.jhs" /> :qk="queryParams.qk" :jhs="queryParams.jhs"/>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
</template> </template>
<script> <script>
...@@ -26,224 +26,236 @@ import CurveGraph from './components/CurveGraph.vue'; ...@@ -26,224 +26,236 @@ import CurveGraph from './components/CurveGraph.vue';
import HistogramGraph from './components/HistogramGraph.vue'; import HistogramGraph from './components/HistogramGraph.vue';
export default { export default {
name: "DjxxDetail", name: "DjxxDetail",
components: { components: {
DataTable, DataTable,
CurveGraph, CurveGraph,
HistogramGraph HistogramGraph
}, },
data() { data() {
return { return {
// 当前激活的tab // 当前激活的tab
activeTab: 'dataTable', activeTab: 'dataTable',
// 显示搜索条件 // 显示搜索条件
showSearch: true, showSearch: true,
// 遮罩层 // 遮罩层
loading: false, loading: false,
// 选中数组 // 选中数组
ids: [], ids: [],
// 查询参数 // 查询参数
queryParams: { queryParams: {
jh: '', jh: '',
famc: '', famc: '',
qk: '', qk: '',
jhs: '' jhs: '',
}, kc: '',
// 标记是否是第一次进入页面 ztccs: '',
isFirstLoad: true },
}; // 标记是否是第一次进入页面
}, isFirstLoad: true
created() { };
// 获取路由参数(使用query) },
console.log('详情页面created,完整路由对象:', this.$route); created() {
let { id, jh, famc, qk, jhs } = this.$route.query || {}; // 获取路由参数(使用query)
console.log('路由query参数:', { id, jh, famc, qk, jhs }); console.log('详情页面created,完整路由对象:', this.$route);
// 优先使用query,其次使用sessionStorage let {id, jh, famc, qk, jhs, kc, ztccs} = this.$route.query || {};
if (!jh || jh === 'undefined' || jh === 'null') { console.log('路由query参数:', {id, jh, famc, qk, jhs, kc, ztccs});
try { // 优先使用query,其次使用sessionStorage
const cached = JSON.parse(sessionStorage.getItem('djxxDetailParams') || '{}'); if (!jh || jh === 'undefined' || jh === 'null') {
({ id, jh, famc, qk, jhs } = { ...cached, ...this.$route.query }); try {
console.log('使用缓存参数:', { id, jh, famc, qk, jhs }); const cached = JSON.parse(sessionStorage.getItem('djxxDetailParams') || '{}');
} catch (e) { ({id, jh, famc, qk, jhs, kc, ztccs} = {...cached, ...this.$route.query});
console.warn('读取缓存失败', e); console.log('使用缓存参数:', {id, jh, famc, qk, jhs, kc, ztccs});
} } catch (e) {
} console.warn('读取缓存失败', e);
if (jh && jh !== 'undefined' && jh !== 'null') { }
this.queryParams.id = id || ''; }
this.queryParams.jh = jh || ''; if (jh && jh !== 'undefined' && jh !== 'null') {
this.queryParams.famc = famc || ''; this.queryParams.id = id || '';
this.queryParams.qk = qk || ''; this.queryParams.jh = jh || '';
this.queryParams.jhs = jhs || ''; this.queryParams.famc = famc || '';
// 缓存参数,便于刷新后保留 this.queryParams.qk = qk || '';
sessionStorage.setItem('djxxDetailParams', JSON.stringify(this.queryParams)); this.queryParams.jhs = jhs || '';
console.log('设置并缓存 queryParams:', this.queryParams); this.queryParams.kc = kc || '';
// 进入页面后,按当前激活的tab触发一次加载 this.queryParams.ztccs = ztccs || '';
this.$nextTick(() => this.refreshActiveTab()); // 缓存参数,便于刷新后保留
} else { sessionStorage.setItem('djxxDetailParams', JSON.stringify(this.queryParams));
console.warn('未获取到有效的参数 jh'); console.log('设置并缓存 queryParams:', this.queryParams);
// 进入页面后,按当前激活的tab触发一次加载
this.$nextTick(() => this.refreshActiveTab());
} else {
console.warn('未获取到有效的参数 jh');
}
// 确保第一次进入页面时不会自动初始化组件
console.log('页面初始化完成,等待用户点击tab');
},
activated() {
// 组件被 keep-alive 缓存时,返回本页会触发此钩子
const {id, jh, famc, qk, jhs,kc,ztccs} = 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 || '';
this.queryParams.kc = kc || '';
this.queryParams.ztccs = ztccs || '';
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) {
console.log('页面初始化完成,等待用户点击tab'); }
}
},
beforeRouteUpdate(to, from, next) {
// 同一路由切换不同 query 时触发
const {id, jh, famc, qk, jhs,kc,ztccs} = 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 || '';
this.queryParams.kc = kc || '';
this.queryParams.ztccs = ztccs || '';
sessionStorage.setItem('djxxDetailParams', JSON.stringify(this.queryParams));
this.$nextTick(() => this.refreshActiveTab());
}
next();
},
watch: {
// 当从列表页连续点击"查看"跳转到同一路由时,组件会复用,这里监听路由变化并刷新当前激活tab
'$route.query'(to) {
const {id, jh, famc, qk, jhs,kc,ztccs} = 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 || '';
this.queryParams.kc = kc || '';
this.queryParams.ztccs = ztccs || '';
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: {
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();
}
}, },
activated() { /** 搜索按钮操作 */
// 组件被 keep-alive 缓存时,返回本页会触发此钩子 handleQuery() {
const { id, jh, famc, qk, jhs } = this.$route.query || {}; this.loading = true;
if (jh && jh !== 'undefined' && jh !== 'null') { // 这里可以调用API进行数据查询
this.queryParams.id = id || ''; setTimeout(() => {
this.queryParams.jh = jh || ''; this.loading = false;
this.queryParams.famc = famc || ''; }, 1000);
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 || {}; handleRemove() {
if (jh && jh !== 'undefined' && jh !== 'null') { if (this.ids.length === 0) {
this.queryParams.id = id || ''; this.$message.warning('请选择要移除的记录');
this.queryParams.jh = jh || ''; return;
this.queryParams.famc = famc || ''; }
this.queryParams.qk = qk || ''; this.$modal.confirm('是否确认移除选中的记录?').then(() => {
this.queryParams.jhs = jhs || ''; // 这里可以调用API进行删除操作
sessionStorage.setItem('djxxDetailParams', JSON.stringify(this.queryParams)); this.$modal.msgSuccess("移除成功");
this.$nextTick(() => this.refreshActiveTab()); }).catch(() => {
} });
next();
}, },
watch: {
// 当从列表页连续点击"查看"跳转到同一路由时,组件会复用,这里监听路由变化并刷新当前激活tab // 多选框选中数据
'$route.query'(to) { handleSelectionChange(selection) {
const { id, jh, famc, qk, jhs } = to || {}; this.ids = selection.map(item => item.id);
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: {
refreshActiveTab() { /** tab切换事件 */
// 每次调用都执行loadData handleTabClick(tab) {
if (this.activeTab === 'dataTable') { console.log('切换到tab:', tab.name);
this.$refs.dataTableRef && this.$refs.dataTableRef.loadData && this.$refs.dataTableRef.loadData(); // 标记已经不是第一次加载
} else if (this.activeTab === 'curveGraph') { this.isFirstLoad = false;
this.$refs.curveGraphRef && this.$refs.curveGraphRef.loadData && this.$refs.curveGraphRef.loadData();
} else if (this.activeTab === 'histogramGraph') { // 每次点击tab都调用loadData
this.$refs.histogramGraphRef && this.$refs.histogramGraphRef.loadData && this.$refs.histogramGraphRef.loadData(); if (tab.name === 'dataTable') {
} this.$refs.dataTableRef && this.$refs.dataTableRef.loadData && this.$refs.dataTableRef.loadData();
}, } else if (tab.name === 'curveGraph') {
/** 搜索按钮操作 */ this.$refs.curveGraphRef && this.$refs.curveGraphRef.loadData && this.$refs.curveGraphRef.loadData();
handleQuery() { } else if (tab.name === 'histogramGraph') {
this.loading = true; this.$refs.histogramGraphRef && this.$refs.histogramGraphRef.loadData && this.$refs.histogramGraphRef.loadData();
// 这里可以调用API进行数据查询 }
setTimeout(() => {
this.loading = false;
}, 1000);
},
/** 移除记录按钮操作 */
handleRemove() {
if (this.ids.length === 0) {
this.$message.warning('请选择要移除的记录');
return;
}
this.$modal.confirm('是否确认移除选中的记录?').then(() => {
// 这里可以调用API进行删除操作
this.$modal.msgSuccess("移除成功");
}).catch(() => { });
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id);
},
/** tab切换事件 */
handleTabClick(tab) {
console.log('切换到tab:', tab.name);
// 标记已经不是第一次加载
this.isFirstLoad = false;
// 每次点击tab都调用loadData
if (tab.name === 'dataTable') {
this.$refs.dataTableRef && this.$refs.dataTableRef.loadData && this.$refs.dataTableRef.loadData();
} else if (tab.name === 'curveGraph') {
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();
}
}
} }
}
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.app-container { .app-container {
padding: 10px; padding: 10px;
box-sizing: border-box; box-sizing: border-box;
} }
.tab-content { .tab-content {
padding: 5px 0; padding: 5px 0;
} }
.chart-container { .chart-container {
height: calc(100vh - 300px); height: calc(100vh - 300px);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
background-color: #f5f5f5; background-color: #f5f5f5;
border-radius: 4px; border-radius: 4px;
h3 {
color: #666;
margin-bottom: 10px;
}
p { h3 {
color: #999; color: #666;
} margin-bottom: 10px;
}
p {
color: #999;
}
} }
::v-deep .el-table__cell>.cell { ::v-deep .el-table__cell > .cell {
font-weight: normal; font-weight: normal;
} }
::v-deep .el-table--medium .el-table__cell { ::v-deep .el-table--medium .el-table__cell {
padding: 5px 0 !important; padding: 5px 0 !important;
} }
::v-deep .el-form-item { ::v-deep .el-form-item {
margin-bottom: 10px !important; margin-bottom: 10px !important;
} }
::v-deep .el-tabs__content { ::v-deep .el-tabs__content {
padding: 5px 0; padding: 5px 0;
margin-top: -10px; margin-top: -10px;
} }
</style> </style>
<template> <template>
<div class="djxx-container"> <div class="djxx-container">
<!-- 搜索条件 --> <!-- 搜索条件 -->
<div class="search-form"> <div class="search-form">
<el-form :model="searchForm" ref="searchFormRef" :rules="searchRules" inline> <el-form :model="searchForm" ref="searchFormRef" :rules="searchRules" inline>
<el-form-item label="区块名称" prop="qk"> <el-form-item label="区块名称" prop="qk">
<el-select v-model="searchForm.qk" placeholder="请选择区块名称" clearable filterable style="width: 150px;"> <el-select v-model="searchForm.qk" placeholder="请选择区块名称" clearable filterable style="width: 150px;">
<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"/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="井号" prop="jh"> <el-form-item label="井号" prop="jh">
<el-input v-model="searchForm.jh" placeholder="请输入" style="width: 150px;" /> <el-input v-model="searchForm.jh" placeholder="请输入" style="width: 150px;"/>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" @click="getList">搜索</el-button> <el-button type="primary" @click="getList">搜索</el-button>
<el-button @click="resetSearch">重置</el-button> <el-button @click="resetSearch">重置</el-button>
<el-button type="success" @click="handleAdd">新增</el-button> <el-button type="success" @click="handleAdd">新增</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
<!-- 数据表格 --> <!-- 数据表格 -->
<el-table :data="tableData" border style="width: 100%; height: calc(100vh - 230px)"> <el-table :data="tableData" border style="width: 100%; height: calc(100vh - 230px)">
<el-table-column prop="famc" label="方案名称" min-width="180" align="center" show-overflow-tooltip sortable /> <el-table-column prop="famc" label="方案名称" min-width="180" align="center" show-overflow-tooltip sortable/>
<el-table-column prop="qk" label="区块" min-width="110" align="center" show-overflow-tooltip sortable /> <el-table-column prop="qk" label="区块" min-width="110" align="center" show-overflow-tooltip sortable/>
<el-table-column prop="jh" label="井号" min-width="110" align="center" show-overflow-tooltip sortable /> <el-table-column prop="jh" label="井号" min-width="110" align="center" show-overflow-tooltip sortable/>
<el-table-column prop="jhs" label="邻井井号" min-width="160" align="center" show-overflow-tooltip sortable /> <el-table-column prop="jhs" label="邻井井号" min-width="160" align="center" show-overflow-tooltip sortable/>
<el-table-column prop="yxzt" label="综合最优" align="center" min-width="160" show-overflow-tooltip sortable /> <el-table-column prop="yxzt" label="综合最优" align="center" min-width="160" show-overflow-tooltip sortable/>
<el-table-column prop="jczt" label="进尺最优" align="center" min-width="160" show-overflow-tooltip sortable /> <el-table-column prop="jczt" label="进尺最优" align="center" min-width="160" show-overflow-tooltip sortable/>
<el-table-column prop="jxzszt" label="转速最优" align="center" min-width="160" show-overflow-tooltip sortable /> <el-table-column prop="jxzszt" label="转速最优" align="center" min-width="160" show-overflow-tooltip sortable/>
<el-table-column label="操作" width="200" align="center" fixed="right"> <el-table-column label="操作" width="200" align="center" fixed="right">
<template slot-scope="scope"> <template slot-scope="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>
<el-button size="mini" type="text" icon="el-icon-edit" <el-button size="mini" type="text" icon="el-icon-edit"
@click="handleUpdate(scope.row)">编辑</el-button> @click="handleUpdate(scope.row)">编辑
<el-button size="mini" type="text" icon="el-icon-delete" </el-button>
@click="handleDelete(scope.row)">删除</el-button> <el-button size="mini" type="text" icon="el-icon-delete"
</template> @click="handleDelete(scope.row)">删除
</el-table-column> </el-button>
</el-table> </template>
<!-- 主表格分页组件 --> </el-table-column>
<el-pagination style="margin-top: 10px; text-align: right;" background </el-table>
layout="total, sizes, prev, pager, next, jumper" :total="mainPagination.total" <!-- 主表格分页组件 -->
:page-sizes="[10, 20, 50, 100]" :page-size="mainPagination.pageSize" :current-page="mainPagination.pageNum" <el-pagination style="margin-top: 10px; text-align: right;" background
@size-change="handleMainSizeChange" @current-change="handleMainCurrentChange" /> layout="total, sizes, prev, pager, next, jumper" :total="mainPagination.total"
:page-sizes="[10, 20, 50, 100]" :page-size="mainPagination.pageSize"
<!-- 新增/编辑弹窗 --> :current-page="mainPagination.pageNum"
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="60%" :close-on-click-modal="false" @size-change="handleMainSizeChange" @current-change="handleMainCurrentChange"/>
@close="handleDialogClose" label-width="100px">
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="140px"> <!-- 新增/编辑弹窗 -->
<el-row> <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="60%" :close-on-click-modal="false"
<el-col :span="12"> @close="handleDialogClose" label-width="100px">
<el-form-item label="方案名称" prop="famc"> <el-form :model="formData" ref="formRef" :rules="formRules" label-width="140px">
<el-input v-model="formData.famc" placeholder="请输入方案名称" /> <el-row>
</el-form-item> <el-col :span="12">
</el-col> <el-form-item label="方案名称" prop="famc">
<el-col :span="12"> <el-input v-model="formData.famc" placeholder="请输入方案名称"/>
<el-form-item label="区块" prop="qk"> </el-form-item>
<el-select v-model="formData.qk" placeholder="请选择区块名称" clearable filterable </el-col>
style="width: 100%;"> <el-col :span="12">
<el-option v-for="item in blockOptions" :key="item.qk" :label="item.qk" :value="item.qk" <el-form-item label="区块" prop="qk">
style="width: 100%;" /> <el-select v-model="formData.qk" placeholder="请选择区块名称" clearable filterable
</el-select> style="width: 100%;">
</el-form-item> <el-option v-for="item in blockOptions" :key="item.qk" :label="item.qk" :value="item.qk"
</el-col> style="width: 100%;"/>
</el-row> </el-select>
<el-row> </el-form-item>
<el-col :span="12"> </el-col>
<el-form-item label="井号" prop="jh"> </el-row>
<div style="cursor: pointer;"> <el-row>
<el-input v-model="formData.jh" placeholder="请输入井号" /> <el-col :span="12">
</div> <el-form-item label="井号" prop="jh">
</el-form-item> <div style="cursor: pointer;">
</el-col> <el-input v-model="formData.jh" placeholder="请输入井号"/>
<el-col :span="12"> </div>
<el-form-item label="井口距离" prop="jl"> </el-form-item>
<el-input v-model="formData.jl" placeholder="请输入" style="width: 100%;" /> </el-col>
</el-form-item> <el-col :span="12">
</el-col> <el-form-item label="井口距离" prop="jl">
</el-row> <el-input v-model="formData.jl" placeholder="请输入" style="width: 100%;"/>
<el-row> </el-form-item>
<el-col :span="12"> </el-col>
<el-form-item label="完井时间" prop="wjsjks" required> </el-row>
<el-date-picker v-model="formData.wjsjks" type="date" placeholder="选择开始日期" <el-row>
style="width: 50%;" /> <el-col :span="12">
<el-date-picker v-model="formData.wjsjjs" type="date" placeholder="选择结束日期" <el-form-item label="完井时间" prop="wjsjks" required>
style="width: 50%;" /> <el-date-picker v-model="formData.wjsjks" type="date" placeholder="选择开始日期"
</el-form-item> style="width: 50%;"/>
</el-col> <el-date-picker v-model="formData.wjsjjs" type="date" placeholder="选择结束日期"
<el-col :span="12"> style="width: 50%;"/>
<el-form-item label="开次" prop="kc"> </el-form-item>
<el-input v-model="formData.kc" placeholder="请输入开次" /> </el-col>
</el-form-item> <el-col :span="12">
</el-col> <el-form-item label="开次" prop="kc">
</el-row> <el-select v-model="formData.kc" filterable placeholder="请选择或输入钻头尺寸" style="width: 100%">
<el-row> <el-option v-for="item in kcData" :key="item.value" :label="item.label"
<el-col :span="12"> :value="item.value"/>
<el-form-item label="井眼尺寸" prop="jycc"> </el-select>
<el-input v-model="formData.jycc" placeholder="请输入井眼尺寸" /> </el-form-item>
</el-form-item> </el-col>
</el-col> </el-row>
<el-col :span="12"> <el-row>
<el-form-item label="选择邻井" prop="jhs"> <el-col :span="12">
<div style="cursor: pointer;" @click="handleSelectAdjacentWell"> <el-form-item label="井眼尺寸" prop="jycc">
<el-input v-model="formData.jhs" placeholder="请点击选择邻井" readonly <el-input v-model="formData.jycc" placeholder="请输入井眼尺寸"/>
style="cursor: pointer;" /> </el-form-item>
</div> </el-col>
</el-form-item> <el-col :span="12">
</el-col> <el-form-item label="选择邻井" prop="jhs">
</el-row> <div style="cursor: pointer;" @click="handleSelectAdjacentWell">
<el-row> <el-input v-model="formData.jhs" placeholder="请点击选择邻井" readonly
<el-col :span="12"> style="cursor: pointer;"/>
<el-form-item label="进尺最优比例" prop="jcbl" required> </div>
<el-select v-model="formData.jcbl" placeholder="请选择进尺最优比例" clearable style="width: 100%;"> </el-form-item>
<el-option label="0.2" value="0.2" /> </el-col>
<el-option label="0.3" value="0.3" /> </el-row>
<el-option label="0.4" value="0.4" /> <el-row>
<el-option label="0.5" value="0.5" /> <el-col :span="12">
</el-select> <el-form-item label="进尺最优比例" prop="jcbl" required>
</el-form-item> <el-slider v-model="formData.jcbl" :max="1" :min="0" :step="0.1" :format-tooltip="formatTooltip"></el-slider>
</el-col> </el-form-item>
<el-col :span="12"> </el-col>
<el-form-item label="机械钻速最优比例" prop="jxzsbl" required> <el-col :span="12">
<el-select v-model="formData.jxzsbl" placeholder="请选择机械钻速最优比例" clearable <el-form-item label="机械钻速最优比例" prop="jxzsbl" required>
style="width: 100%;"> <el-slider v-model="formData.jxzsbl" :max="1" :min="0" :step="0.1" :format-tooltip="formatTooltip"></el-slider>
<el-option label="0.2" value="0.2" />
<el-option label="0.3" value="0.3" /> </el-form-item>
<el-option label="0.4" value="0.4" /> </el-col>
<el-option label="0.5" value="0.5" /> </el-row>
</el-select> </el-form>
</el-form-item> <template slot="footer">
</el-col>
</el-row>
</el-form>
<template slot="footer">
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button> <el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="submitForm">确 定</el-button> <el-button type="primary" @click="submitForm">确 定</el-button>
</span> </span>
</template> </template>
</el-dialog> </el-dialog>
<!-- 井号选择弹窗 --> <!-- 井号选择弹窗 -->
<el-dialog title="选择邻井" :visible.sync="wellDialogVisible" width="80%" :close-on-click-modal="false" <el-dialog title="选择邻井" :visible.sync="wellDialogVisible" width="80%" :close-on-click-modal="false"
class="well-dialog" :z-index="2000"> class="well-dialog" :z-index="2000">
<!-- 选择提示信息 --> <!-- 选择提示信息 -->
<!-- <div <!-- <div
style="margin-bottom: 15px; padding: 10px; background-color: #f0f9ff; border: 1px solid #b3d8ff; border-radius: 4px; color: #1890ff;"> style="margin-bottom: 15px; padding: 10px; background-color: #f0f9ff; border: 1px solid #b3d8ff; border-radius: 4px; color: #1890ff;">
<i class="el-icon-info"></i> <i class="el-icon-info"></i>
<span>提示:您最多可以选择2个邻井,当前已选择 {{ wellSelection.length }} 个</span> <span>提示:您最多可以选择2个邻井,当前已选择 {{ wellSelection.length }} 个</span>
</div> --> </div> -->
<el-table :data="wellTableData" border style="width: 100%;height: 400px" max-height="400px" <el-table :data="wellTableData" border style="width: 100%;height: 400px" max-height="400px"
v-loading="wellLoading" @selection-change="handleWellSelectionChange" ref="wellTable" v-loading="wellLoading" @selection-change="handleWellSelectionChange" ref="wellTable"
:row-key="row => row.jh"> :row-key="row => row.jh">
<el-table-column type="selection" width="55" :selectable="checkSelectable" /> <el-table-column type="selection" width="55" :selectable="checkSelectable"/>
<el-table-column prop="jh" label="井号" align="center" show-overflow-tooltip /> <el-table-column prop="jh" label="井号" align="center" show-overflow-tooltip/>
<el-table-column prop="jx" label="井型" align="center" show-overflow-tooltip /> <el-table-column prop="jx" label="井型" align="center" show-overflow-tooltip/>
<el-table-column prop="wjjs" label="斜深" align="center" show-overflow-tooltip /> <el-table-column prop="wjjs" label="斜深" align="center" show-overflow-tooltip/>
<el-table-column prop="wjczjs" label="垂深" align="center" show-overflow-tooltip /> <el-table-column prop="wjczjs" label="垂深" align="center" show-overflow-tooltip/>
<el-table-column prop="wzcw" label="完钻层位" align="center" show-overflow-tooltip /> <el-table-column prop="wzcw" label="完钻层位" align="center" show-overflow-tooltip/>
<el-table-column prop="kc" label="总开次" align="center" show-overflow-tooltip /> <el-table-column prop="kc" label="总开次" align="center" show-overflow-tooltip/>
<el-table-column prop="zjzq" label="钻井周期(天)" align="center" show-overflow-tooltip /> <el-table-column prop="zjzq" label="钻井周期(天)" align="center" show-overflow-tooltip/>
<el-table-column prop="wjzq" label="钻完周期(天)" align="center" show-overflow-tooltip /> <el-table-column prop="wjzq" label="钻完周期(天)" align="center" show-overflow-tooltip/>
<el-table-column prop="jkjl" label="井口距离" align="center" show-overflow-tooltip /> <el-table-column prop="jkjl" label="井口距离" align="center" show-overflow-tooltip/>
<!-- <el-table-column prop="jdjl" label="井底距离" align="center" show-overflow-tooltip /> --> <!-- <el-table-column prop="jdjl" label="井底距离" align="center" show-overflow-tooltip /> -->
</el-table> </el-table>
<!-- 分页组件 --> <!-- 分页组件 -->
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
:current-page="wellPagination.pageNum" :page-sizes="[10, 20, 50, 100]" :current-page="wellPagination.pageNum" :page-sizes="[10, 20, 50, 100]"
:page-size="wellPagination.pageSize" layout="total, sizes, prev, pager, next, jumper" :page-size="wellPagination.pageSize" layout="total, sizes, prev, pager, next, jumper"
:total="wellPagination.total" style="margin-top: 10px; text-align: right;" /> :total="wellPagination.total" style="margin-top: 10px; text-align: right;"/>
<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>
</div> </div>
</template> </template>
<script> <script>
import { listSj } from '@/api/adjacentWell' import {listSj} from '@/api/adjacentWell'
import { getQkxl } from "@/api/system/jsaa"; import {getQkxl} from "@/api/system/jsaa";
import { listDjnxfxfa, getDjnxfxfa, delDjnxfxfa, addDjnxfxfa, updateDjnxfxfa } from "@/api/system/djnxfxfa"; import {listDjnxfxfa, getDjnxfxfa, delDjnxfxfa, addDjnxfxfa, updateDjnxfxfa} from "@/api/system/djnxfxfa";
export default { export default {
name: 'DjxxIndex', name: 'DjxxIndex',
dicts: ['qkinfo', 'js_jx', 'js_jb'], dicts: ['qkinfo', 'js_jx', 'js_jb'],
data() { data() {
return { return {
blockOptions: [], blockOptions: [],
// 搜索表单 // 搜索表单
searchForm: { searchForm: {
qk: '' qk: ''
}, },
searchRules: { searchRules: {},
}, // 表格数据
tableData: [],
// 表格数据
tableData: [], // 弹窗相关
dialogVisible: false,
// 弹窗相关 dialogTitle: '',
dialogVisible: false, formData: {
dialogTitle: '', famc: '',
formData: { qk: '',
famc: '', jhs: '',
qk: '', kc: '',
jhs: '', jycc: '',
kc: '', jl: '10000', // 距离默认值10000
jycc: '', wjsjks: null, // 完井时间开始默认五年前的今天
jl: '10000', // 距离默认值10000 wjsjjs: null, // 完井时间结束默认今天
wjsjks: null, // 完井时间开始默认五年前的今天 jcbl: 0.2, // 进尺最优比例
wjsjjs: null, // 完井时间结束默认今天 jxzsbl: 0.2 // 机械钻速最优比例
jcbl: '', // 进尺最优比例 },
jxzsbl: '' // 机械钻速最优比例 formRules: {
}, famc: [{required: true, message: '请输入方案名称', trigger: 'blur'}],
formRules: { qk: [{required: true, message: '请选择区块', trigger: 'change'}],
famc: [{ required: true, message: '请输入方案名称', trigger: 'blur' }], jhs: [{required: true, message: '请选择井号', trigger: 'change'}],
qk: [{ required: true, message: '请选择区块', trigger: 'change' }], jcbl: [{required: true, message: '请选择进尺最优比例', trigger: 'change'}],
jhs: [{ required: true, message: '请选择井号', trigger: 'change' }], jxzsbl: [{required: true, message: '请选择机械钻速最优比例', trigger: 'change'}]
jcbl: [{ required: true, message: '请选择进尺最优比例', trigger: 'change' }], },
jxzsbl: [{ required: true, message: '请选择机械钻速最优比例', trigger: 'change' }]
}, // 井号选择弹窗
wellDialogVisible: false,
// 井号选择弹窗 wellTableData: [],
wellDialogVisible: false, wellLoading: false,
wellTableData: [], wellSelection: [],
wellLoading: false, wellPagination: {
wellSelection: [], pageNum: 1,
wellPagination: { pageSize: 10,
pageNum: 1, total: 0
pageSize: 10, },
total: 0 isUserSelecting: false,
}, isSettingSelection: false,
isUserSelecting: false, // 添加页面选择状态缓存
isSettingSelection: false, pageSelectionCache: new Map(),
// 添加页面选择状态缓存 // 添加初始化标志
pageSelectionCache: new Map(), isInitializing: false,
// 添加初始化标志 // 主表格分页
isInitializing: false, mainPagination: {
// 主表格分页 pageNum: 1,
mainPagination: { pageSize: 10,
pageNum: 1, total: 0
pageSize: 10, },
total: 0 kcData: [
}, {
label: '1',
value: '1',
}, {
label: '2',
value: '2',
}, {
label: '3',
value: '3',
}, {
label: '4',
value: '4',
}, {
label: '5',
value: '5',
},
]
}
},
created() {
this.getBlockOptions();
this.getList();
// 设置默认日期值
this.formData.wjsjks = this.getFiveYearsAgoDate();
this.formData.wjsjjs = this.getCurrentDate();
},
methods: {
/** 获取五年前的今天 */
getFiveYearsAgoDate() {
const date = new Date();
date.setFullYear(date.getFullYear() - 5);
return date;
},
/** 获取今天的日期 */
getCurrentDate() {
return new Date();
},
/** 格式化日期为 yyyy-MM-dd 格式 */
formatDate(date) {
// 如果date不是Date对象,尝试转换
if (!(date instanceof Date)) {
if (typeof date === 'string') {
date = new Date(date);
} else if (date === null || date === undefined) {
return '';
} else {
console.warn('formatDate received invalid date:', date);
return '';
} }
}
// 检查转换后的日期是否有效
if (isNaN(date.getTime())) {
console.warn('formatDate received invalid date:', date);
return '';
}
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
}, },
created() { /** 查询多井能效分析方案信息列表 */
this.getBlockOptions(); getList() {
this.getList(); this.loading = true;
// 设置默认日期值 // 合并分页参数
this.formData.wjsjks = this.getFiveYearsAgoDate(); const params = {
this.formData.wjsjjs = this.getCurrentDate(); ...this.searchForm,
pageNum: this.mainPagination.pageNum,
pageSize: this.mainPagination.pageSize
};
listDjnxfxfa(params).then(response => {
this.tableData = response.rows;
this.mainPagination.total = response.total;
console.log('获取到的表格数据:', this.tableData);
// 检查每条数据的jhs字段
this.tableData.forEach((row, index) => {
console.log(`第${index + 1}行数据:`, row);
console.log(`第${index + 1}行jhs字段:`, row.jhs);
});
this.loading = false;
});
}, },
methods: { // 取消按钮
/** 获取五年前的今天 */ cancel() {
getFiveYearsAgoDate() { this.open = false;
const date = new Date(); this.reset();
date.setFullYear(date.getFullYear() - 5); },
return date; // 表单重置
}, reset() {
/** 获取今天的日期 */ this.formData = {
getCurrentDate() { famc: '',
return new Date(); qk: '',
}, jhs: '',
/** 格式化日期为 yyyy-MM-dd 格式 */ kc: '',
formatDate(date) { jycc: '',
// 如果date不是Date对象,尝试转换 jl: '10000', // 距离默认值10000
if (!(date instanceof Date)) { wjsjks: this.getFiveYearsAgoDate(), // 完井时间开始默认五年前的今天
if (typeof date === 'string') { wjsjjs: this.getCurrentDate(), // 完井时间结束默认今天
date = new Date(date); jcbl: 0.2, // 进尺最优比例
} else if (date === null || date === undefined) { jxzsbl: 0.2 // 机械钻速最优比例
return ''; };
} else { },
console.warn('formatDate received invalid date:', date); /** 搜索按钮操作 */
return ''; handleQuery() {
} this.queryParams.pageNum = 1;
} this.getList();
},
// 检查转换后的日期是否有效 /** 重置按钮操作 */
if (isNaN(date.getTime())) { resetQuery() {
console.warn('formatDate received invalid date:', date); this.resetForm("queryForm");
return ''; this.handleQuery();
} },
// /** 新增按钮操作 */
const year = date.getFullYear(); // handleAdd() {
const month = String(date.getMonth() + 1).padStart(2, '0'); // this.reset();
const day = String(date.getDate()).padStart(2, '0'); // this.open = true;
return `${year}-${month}-${day}`; // this.title = "添加多井能效分析方案信息";
}, // },
/** 查询多井能效分析方案信息列表 */ /** 修改按钮操作 */
getList() { handleUpdate(row) {
this.loading = true; this.reset();
// 合并分页参数 const id = row.id || this.ids
const params = { getDjnxfxfa(id).then(response => {
...this.searchForm, this.formData = response.data;
pageNum: this.mainPagination.pageNum, // 确保日期字段是Date对象
pageSize: this.mainPagination.pageSize if (this.formData.wjsjks && typeof this.formData.wjsjks === 'string') {
}; this.formData.wjsjks = new Date(this.formData.wjsjks);
listDjnxfxfa(params).then(response => { }
this.tableData = response.rows; if (this.formData.wjsjjs && typeof this.formData.wjsjjs === 'string') {
this.mainPagination.total = response.total; this.formData.wjsjjs = new Date(this.formData.wjsjjs);
console.log('获取到的表格数据:', this.tableData); }
// 检查每条数据的jhs字段 this.dialogVisible = true;
this.tableData.forEach((row, index) => { this.dialogTitle = "修改多井能效分析方案信息";
console.log(`第${index + 1}行数据:`, row); // 编辑时不清空选择状态,保留之前的选择
console.log(`第${index + 1}行jhs字段:`, row.jhs); // this.wellSelection = []
}); // this.pageSelectionCache.clear()
this.loading = false; });
}); },
}, /** 提交按钮 */
// 取消按钮 submitForm() {
cancel() { this.$refs["formRef"].validate(valid => {
this.open = false; if (valid) {
this.reset(); // 格式化日期为字符串格式传给后台
}, const submitData = {
// 表单重置 ...this.formData,
reset() { wjsjks: this.formData.wjsjks ? this.formatDate(this.formData.wjsjks) : '',
this.formData = { wjsjjs: this.formData.wjsjjs ? this.formatDate(this.formData.wjsjjs) : ''
famc: '', };
qk: '',
jhs: '', if (this.formData.id != null) {
kc: '', updateDjnxfxfa(submitData).then(response => {
jycc: '', this.$modal.msgSuccess("修改成功");
jl: '10000', // 距离默认值10000 this.dialogVisible = false;
wjsjks: this.getFiveYearsAgoDate(), // 完井时间开始默认五年前的今天 this.getList();
wjsjjs: this.getCurrentDate(), // 完井时间结束默认今天 // 保存成功后,重置井号选择状态
jcbl: '', // 进尺最优比例 this.wellSelection = []
jxzsbl: '' // 机械钻速最优比例 this.pageSelectionCache.clear()
};
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加多井能效分析方案信息";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids
getDjnxfxfa(id).then(response => {
this.formData = response.data;
// 确保日期字段是Date对象
if (this.formData.wjsjks && typeof this.formData.wjsjks === 'string') {
this.formData.wjsjks = new Date(this.formData.wjsjks);
}
if (this.formData.wjsjjs && typeof this.formData.wjsjjs === 'string') {
this.formData.wjsjjs = new Date(this.formData.wjsjjs);
}
this.dialogVisible = true;
this.dialogTitle = "修改多井能效分析方案信息";
// 编辑时不清空选择状态,保留之前的选择
// this.wellSelection = []
// this.pageSelectionCache.clear()
});
},
/** 提交按钮 */
submitForm() {
this.$refs["formRef"].validate(valid => {
if (valid) {
// 格式化日期为字符串格式传给后台
const submitData = {
...this.formData,
wjsjks: this.formData.wjsjks ? this.formatDate(this.formData.wjsjks) : '',
wjsjjs: this.formData.wjsjjs ? this.formatDate(this.formData.wjsjjs) : ''
};
if (this.formData.id != null) {
updateDjnxfxfa(submitData).then(response => {
this.$modal.msgSuccess("修改成功");
this.dialogVisible = false;
this.getList();
// 保存成功后,重置井号选择状态
this.wellSelection = []
this.pageSelectionCache.clear()
});
} else {
addDjnxfxfa(submitData).then(response => {
this.$modal.msgSuccess("新增成功");
this.dialogVisible = false;
this.getList();
// 保存成功后,重置井号选择状态
this.wellSelection = []
this.pageSelectionCache.clear()
});
}
}
});
},
/** 查看按钮操作 */
handleView(row) {
console.log('查看按钮点击,行数据:', row);
const params = {
id: row.id || '',
jh: row.jh || '',
famc: row.famc || '',
qk: row.qk || '',
jhs: row.jhs || ''
};
console.log('准备传递的参数:', params);
this.$router.push({
name: 'DjxxDetail',
query: params
}).then(() => {
console.log('路由跳转成功');
}).catch(err => {
console.error('路由跳转失败:', err);
}); });
}, } else {
/** 删除按钮操作 */ addDjnxfxfa(submitData).then(response => {
handleDelete(row) { this.$modal.msgSuccess("新增成功");
const ids = row.id || this.ids; this.dialogVisible = false;
this.$modal.confirm('是否确认删除多井能效分析方案信息编号为"' + ids + '"的数据项?').then(function () { this.getList();
return delDjnxfxfa(ids); // 保存成功后,重置井号选择状态
}).then(() => { this.wellSelection = []
this.getList(); this.pageSelectionCache.clear()
this.$modal.msgSuccess("删除成功");
}).catch(() => { });
},
/** 获取区块下拉选项 */
getBlockOptions() {
getQkxl().then(response => {
// 过滤掉无效的选项
this.blockOptions = response.data.filter(item => item && item.qk);
}); });
}, }
}
});
// 重置搜索 },
resetSearch() { /** 查看按钮操作 */
this.$refs.searchFormRef.resetFields() handleView(row) {
this.searchForm = { console.log('查看按钮点击,行数据:', row);
qk: '' const params = {
} id: row.id || '',
this.tableData = [] jh: row.jh || '',
// 重置后重新获取数据 famc: row.famc || '',
this.getList() qk: row.qk || '',
}, jhs: row.jhs || '',
kc: row.kc || '',
// 新增 ztccs: row.jycc || '',
handleAdd() { };
this.dialogTitle = '新增' console.log('准备传递的参数:', params);
this.dialogVisible = true
this.formData = { this.$router.push({
famc: '', name: 'DjxxDetail',
qk: '', query: params
jhs: '', }).then(() => {
kc: '', console.log('路由跳转成功');
jycc: '', }).catch(err => {
jl: '10000', // 距离默认值10000 console.error('路由跳转失败:', err);
wjsjks: this.getFiveYearsAgoDate(), // 完井时间开始默认五年前的今天 });
wjsjjs: this.getCurrentDate(), // 完井时间结束默认今天 },
jcbl: '', // 进尺最优比例 /** 删除按钮操作 */
jxzsbl: '' // 机械钻速最优比例 handleDelete(row) {
} const ids = row.id || this.ids;
// 新增时重置井号选择状态 this.$modal.confirm('是否确认删除多井能效分析方案信息编号为"' + ids + '"的数据项?').then(function () {
this.wellSelection = [] return delDjnxfxfa(ids);
this.pageSelectionCache.clear() }).then(() => {
}, this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {
// 选择邻井 });
handleSelectAdjacentWell() { },
console.log('点击选择邻井输入框') /** 获取区块下拉选项 */
getBlockOptions() {
// 验证必要参数是否已填写 getQkxl().then(response => {
if (!this.formData.qk) { // 过滤掉无效的选项
this.$message.warning('请先选择区块') this.blockOptions = response.data.filter(item => item && item.qk);
return });
} },
if (!this.formData.jh) {
this.$message.warning('请先输入井号')
return // 重置搜索
} resetSearch() {
if (!this.formData.jl) { this.$refs.searchFormRef.resetFields()
this.$message.warning('请先输入距离') this.searchForm = {
return qk: ''
} }
if (!this.formData.wjsjks || !this.formData.wjsjjs) { this.tableData = []
this.$message.warning('请先选择完井时间') // 重置后重新获取数据
return this.getList()
} },
this.dialogVisible = false // 新增
this.wellDialogVisible = true handleAdd() {
this.dialogTitle = '新增'
console.log('弹窗状态:', this.wellDialogVisible) this.dialogVisible = true
// 重置分页 this.formData = {
this.wellPagination.pageNum = 1 famc: '',
this.wellPagination.pageSize = 10 qk: '',
this.wellPagination.total = 0 jhs: '',
kc: '',
// 保留上次的选择状态,不清空 jycc: '',
// this.pageSelectionCache.clear() jl: '10000', // 距离默认值10000
// this.isInitializing = false wjsjks: this.getFiveYearsAgoDate(), // 完井时间开始默认五年前的今天
wjsjjs: this.getCurrentDate(), // 完井时间结束默认今天
// 不清空井号选择状态,保留上次选择 jcbl: 0.2, // 进尺最优比例
// this.wellSelection = [] jxzsbl: 0.2 // 机械钻速最优比例
// this.formData.jhs = '' }
// 新增时重置井号选择状态
// 设置用户选择标志 this.wellSelection = []
this.isUserSelecting = true this.pageSelectionCache.clear()
},
// 自动获取邻井数据
this.$nextTick(() => {
this.fetchWellData() // 选择邻井
}) handleSelectAdjacentWell() {
}, console.log('点击选择邻井输入框')
// 选择井号 // 验证必要参数是否已填写
handleSelectWell() { if (!this.formData.qk) {
console.log('点击井号输入框') this.$message.warning('请先选择区块')
this.dialogVisible = false return
this.wellDialogVisible = true }
if (!this.formData.jh) {
console.log('弹窗状态:', this.wellDialogVisible) this.$message.warning('请先输入井号')
// 重置分页 return
this.wellPagination.pageNum = 1 }
this.wellPagination.pageSize = 10 if (!this.formData.jl) {
this.wellPagination.total = 0 this.$message.warning('请先输入距离')
return
// 重置页面选择缓存和初始化标志 }
this.pageSelectionCache.clear() if (!this.formData.wjsjks || !this.formData.wjsjjs) {
this.isInitializing = false this.$message.warning('请先选择完井时间')
return
// 清空井号选择状态,每次点击都重新开始选择 }
this.wellSelection = []
this.formData.jh = '' this.dialogVisible = false
this.wellDialogVisible = true
// 设置用户选择标志
this.isUserSelecting = true console.log('弹窗状态:', this.wellDialogVisible)
// 重置分页
// 自动获取井号数据 this.wellPagination.pageNum = 1
this.$nextTick(() => { this.wellPagination.pageSize = 10
this.fetchWellData() this.wellPagination.total = 0
})
}, // 保留上次的选择状态,不清空
// this.pageSelectionCache.clear()
// 井号搜索(简化版,直接获取数据) // this.isInitializing = false
handleWellSearch() {
// 保存当前页面的选择状态(如果有的话) // 不清空井号选择状态,保留上次选择
if (this.$refs.wellTable) { // this.wellSelection = []
const currentSelection = this.$refs.wellTable.selection || [] // this.formData.jhs = ''
const currentPageSelection = currentSelection.map(item => item.jh)
if (currentPageSelection.length > 0) { // 设置用户选择标志
this.pageSelectionCache.set(this.wellPagination.pageNum, currentPageSelection) this.isUserSelecting = true
console.log('搜索前保存当前页面选择:', currentPageSelection)
} // 自动获取邻井数据
} this.$nextTick(() => {
this.fetchWellData()
this.fetchWellData() })
}, },
// 获取井号数据 // 选择井号
fetchWellData() { handleSelectWell() {
this.wellLoading = true console.log('点击井号输入框')
this.isInitializing = true this.dialogVisible = false
this.wellDialogVisible = true
const params = {
pageNum: this.wellPagination.pageNum, console.log('弹窗状态:', this.wellDialogVisible)
pageSize: this.wellPagination.pageSize, // 重置分页
// 传递表单参数 this.wellPagination.pageNum = 1
qk: this.formData.qk || '', // 区块 this.wellPagination.pageSize = 10
jh: this.formData.jh || '', // 井号 this.wellPagination.total = 0
jl: this.formData.jl || '', // 距离
wjsjks: this.formData.wjsjks ? this.formatDate(this.formData.wjsjks) : '', // 完井时间开始 // 重置页面选择缓存和初始化标志
wjsjjs: this.formData.wjsjjs ? this.formatDate(this.formData.wjsjjs) : '' // 完井时间结束 this.pageSelectionCache.clear()
} this.isInitializing = false
listSj(params).then(res => {
this.wellTableData = res.rows || [] // 清空井号选择状态,每次点击都重新开始选择
this.wellPagination.total = res.total || 0 this.wellSelection = []
console.log('数据加载完成,准备设置选择状态') this.formData.jh = ''
// 如果是第一次打开弹窗,需要从formData.jhs中恢复选择状态 // 设置用户选择标志
if (this.wellSelection.length === 0 && this.formData.jhs) { this.isUserSelecting = true
const selectedWells = this.formData.jhs.split(',').filter(well => well.trim())
this.wellSelection = selectedWells // 自动获取井号数据
console.log('从formData.jhs恢复选择状态:', selectedWells) this.$nextTick(() => {
} this.fetchWellData()
})
// 完全禁用选择变化事件处理 },
this.isUserSelecting = false
this.isSettingSelection = true // 井号搜索(简化版,直接获取数据)
handleWellSearch() {
// 延迟设置选择状态,确保DOM更新完成且不会触发选择变化事件 // 保存当前页面的选择状态(如果有的话)
setTimeout(() => { if (this.$refs.wellTable) {
this.setCurrentPageSelection() const currentSelection = this.$refs.wellTable.selection || []
}, 200) const currentPageSelection = currentSelection.map(item => item.jh)
}).catch(error => { if (currentPageSelection.length > 0) {
this.$message.error('获取井号数据失败') this.pageSelectionCache.set(this.wellPagination.pageNum, currentPageSelection)
}).finally(() => { console.log('搜索前保存当前页面选择:', currentPageSelection)
this.wellLoading = false }
}) }
},
this.fetchWellData()
// 重置井号搜索(简化版) },
resetWellSearch() {
this.wellTableData = [] // 获取井号数据
this.wellSelection = [] fetchWellData() {
this.wellPagination.pageNum = 1 this.wellLoading = true
this.isInitializing = true
// 重置页面选择缓存
this.pageSelectionCache.clear() const params = {
pageNum: this.wellPagination.pageNum,
// 重置后自动获取数据 pageSize: this.wellPagination.pageSize,
this.$nextTick(() => { // 传递表单参数
this.fetchWellData() qk: this.formData.qk || '', // 区块
}) jh: this.formData.jh || '', // 井号
}, jl: this.formData.jl || '', // 距离
wjsjks: this.formData.wjsjks ? this.formatDate(this.formData.wjsjks) : '', // 完井时间开始
// 检查是否可选 wjsjjs: this.formData.wjsjjs ? this.formatDate(this.formData.wjsjjs) : '' // 完井时间结束
checkSelectable(row) { }
// 取消数量限制,所有行都可选择 listSj(params).then(res => {
return true this.wellTableData = res.rows || []
}, this.wellPagination.total = res.total || 0
console.log('数据加载完成,准备设置选择状态')
// 设置当前页面的选择状态
setCurrentPageSelection() { // 如果是第一次打开弹窗,需要从formData.jhs中恢复选择状态
if (!this.$refs.wellTable) { if (this.wellSelection.length === 0 && this.formData.jhs) {
return const selectedWells = this.formData.jhs.split(',').filter(well => well.trim())
} this.wellSelection = selectedWells
console.log('从formData.jhs恢复选择状态:', selectedWells)
console.log('设置页面选择状态,当前选择:', this.wellSelection) }
// 获取当前页面应该选中的井号 // 完全禁用选择变化事件处理
let currentPageSelection = this.pageSelectionCache.get(this.wellPagination.pageNum) || [] this.isUserSelecting = false
this.isSettingSelection = true
// 如果是第一次加载且没有缓存,从总选择中筛选当前页面的井号
if (currentPageSelection.length === 0 && this.wellSelection.length > 0) { // 延迟设置选择状态,确保DOM更新完成且不会触发选择变化事件
currentPageSelection = this.wellSelection.filter(well => setTimeout(() => {
this.wellTableData.some(row => row.jh === well) this.setCurrentPageSelection()
) }, 200)
// 更新缓存 }).catch(error => {
this.pageSelectionCache.set(this.wellPagination.pageNum, currentPageSelection) this.$message.error('获取井号数据失败')
console.log('从总选择中筛选当前页面井号:', currentPageSelection) }).finally(() => {
} this.wellLoading = false
})
console.log('当前页面应该选中的井号:', currentPageSelection) },
// 先清除所有选择
this.$refs.wellTable.clearSelection()
// 设置当前页面的选择状态
this.wellTableData.forEach(row => {
const isSelected = currentPageSelection.includes(row.jh)
if (isSelected) {
this.$refs.wellTable.toggleRowSelection(row, true)
console.log('选中行:', row.jh)
}
})
// 延迟恢复标志,确保选择状态设置完成且不会触发选择变化事件
setTimeout(() => {
this.isUserSelecting = true
this.isSettingSelection = false
this.isInitializing = false
console.log('恢复用户选择标志,设置完成')
}, 500)
},
// 分页大小改变
handleSizeChange(size) {
// 保存当前页面的选择状态
if (this.$refs.wellTable) {
const currentSelection = this.$refs.wellTable.selection || []
const currentPageSelection = currentSelection.map(item => item.jh)
this.pageSelectionCache.set(this.wellPagination.pageNum, currentPageSelection)
console.log('保存当前页面选择:', currentPageSelection)
}
this.wellPagination.pageSize = size
this.wellPagination.pageNum = 1
this.fetchWellData()
},
// 当前页改变
handleCurrentChange(page) {
console.log('翻页前选择状态:', this.wellSelection)
// 保存当前页面的选择状态
if (this.$refs.wellTable) {
const currentSelection = this.$refs.wellTable.selection || []
const currentPageSelection = currentSelection.map(item => item.jh)
this.pageSelectionCache.set(this.wellPagination.pageNum, currentPageSelection)
console.log('保存当前页面选择:', currentPageSelection)
}
this.wellPagination.pageNum = page
this.fetchWellData()
},
// 井号选择变化
handleWellSelectionChange(selection) {
console.log('选择变化事件触发,selection长度:', selection.length, 'isUserSelecting:', this.isUserSelecting, 'isSettingSelection:', this.isSettingSelection, 'isInitializing:', this.isInitializing)
// 如果是页面初始化或正在设置选择状态,不处理选择变化
if (!this.isUserSelecting || this.isSettingSelection || this.isInitializing) {
console.log('页面初始化或正在设置选择状态,跳过选择变化处理')
return
}
// 获取当前页面选中的井号
const currentPageSelection = selection.map(item => item.jh)
console.log('当前页面选择:', currentPageSelection)
// 缓存当前页面的选择状态
this.pageSelectionCache.set(this.wellPagination.pageNum, currentPageSelection)
// 重新构建总的选择列表
let allSelectedWells = []
// 从缓存中获取所有页面的选择
for (let pageNum = 1; pageNum <= Math.ceil(this.wellPagination.total / this.wellPagination.pageSize); pageNum++) {
const pageSelection = this.pageSelectionCache.get(pageNum) || []
allSelectedWells.push(...pageSelection)
}
this.wellSelection = allSelectedWells
console.log('最终选择状态:', this.wellSelection)
},
// 井号确定按钮点击
handleWellSubmit() {
if (this.wellSelection.length === 0) {
this.$message.warning('请选择邻井')
return
}
console.log('提交时的选择:', this.wellSelection)
// 邻井选择,用逗号隔开显示
this.formData.jhs = this.wellSelection.join(',')
console.log('赋值到邻井输入框:', this.formData.jhs)
this.$message.success(`邻井选择成功,已选择${this.wellSelection.length}个井号`)
this.wellDialogVisible = false
// 重新打开主弹窗并清除验证错误
this.$nextTick(() => {
this.dialogVisible = true
// 清除井号字段的验证错误
if (this.$refs.formRef) {
this.$refs.formRef.clearValidate('jhs')
}
})
},
// 井号选择弹窗取消按钮点击
handleWellCancel() {
this.wellDialogVisible = false
// 重新打开主弹窗
this.$nextTick(() => {
this.dialogVisible = true
})
},
// 弹窗关闭处理
handleDialogClose() {
// 弹窗关闭时不清空选择状态,保留选择直到确定提交
// this.wellSelection = []
// this.pageSelectionCache.clear()
},
// 主表格分页事件
handleMainSizeChange(size) {
this.mainPagination.pageSize = size;
this.mainPagination.pageNum = 1;
this.getList();
},
handleMainCurrentChange(page) {
this.mainPagination.pageNum = page;
this.getList();
},
// 重置井号搜索(简化版)
resetWellSearch() {
this.wellTableData = []
this.wellSelection = []
this.wellPagination.pageNum = 1
// 重置页面选择缓存
this.pageSelectionCache.clear()
// 重置后自动获取数据
this.$nextTick(() => {
this.fetchWellData()
})
},
// 检查是否可选
checkSelectable(row) {
// 取消数量限制,所有行都可选择
return true
},
// 设置当前页面的选择状态
setCurrentPageSelection() {
if (!this.$refs.wellTable) {
return
}
console.log('设置页面选择状态,当前选择:', this.wellSelection)
// 获取当前页面应该选中的井号
let currentPageSelection = this.pageSelectionCache.get(this.wellPagination.pageNum) || []
// 如果是第一次加载且没有缓存,从总选择中筛选当前页面的井号
if (currentPageSelection.length === 0 && this.wellSelection.length > 0) {
currentPageSelection = this.wellSelection.filter(well =>
this.wellTableData.some(row => row.jh === well)
)
// 更新缓存
this.pageSelectionCache.set(this.wellPagination.pageNum, currentPageSelection)
console.log('从总选择中筛选当前页面井号:', currentPageSelection)
}
console.log('当前页面应该选中的井号:', currentPageSelection)
// 先清除所有选择
this.$refs.wellTable.clearSelection()
// 设置当前页面的选择状态
this.wellTableData.forEach(row => {
const isSelected = currentPageSelection.includes(row.jh)
if (isSelected) {
this.$refs.wellTable.toggleRowSelection(row, true)
console.log('选中行:', row.jh)
}
})
// 延迟恢复标志,确保选择状态设置完成且不会触发选择变化事件
setTimeout(() => {
this.isUserSelecting = true
this.isSettingSelection = false
this.isInitializing = false
console.log('恢复用户选择标志,设置完成')
}, 500)
},
// 分页大小改变
handleSizeChange(size) {
// 保存当前页面的选择状态
if (this.$refs.wellTable) {
const currentSelection = this.$refs.wellTable.selection || []
const currentPageSelection = currentSelection.map(item => item.jh)
this.pageSelectionCache.set(this.wellPagination.pageNum, currentPageSelection)
console.log('保存当前页面选择:', currentPageSelection)
}
this.wellPagination.pageSize = size
this.wellPagination.pageNum = 1
this.fetchWellData()
},
// 当前页改变
handleCurrentChange(page) {
console.log('翻页前选择状态:', this.wellSelection)
// 保存当前页面的选择状态
if (this.$refs.wellTable) {
const currentSelection = this.$refs.wellTable.selection || []
const currentPageSelection = currentSelection.map(item => item.jh)
this.pageSelectionCache.set(this.wellPagination.pageNum, currentPageSelection)
console.log('保存当前页面选择:', currentPageSelection)
}
this.wellPagination.pageNum = page
this.fetchWellData()
},
// 井号选择变化
handleWellSelectionChange(selection) {
console.log('选择变化事件触发,selection长度:', selection.length, 'isUserSelecting:', this.isUserSelecting, 'isSettingSelection:', this.isSettingSelection, 'isInitializing:', this.isInitializing)
// 如果是页面初始化或正在设置选择状态,不处理选择变化
if (!this.isUserSelecting || this.isSettingSelection || this.isInitializing) {
console.log('页面初始化或正在设置选择状态,跳过选择变化处理')
return
}
// 获取当前页面选中的井号
const currentPageSelection = selection.map(item => item.jh)
console.log('当前页面选择:', currentPageSelection)
// 缓存当前页面的选择状态
this.pageSelectionCache.set(this.wellPagination.pageNum, currentPageSelection)
// 重新构建总的选择列表
let allSelectedWells = []
// 从缓存中获取所有页面的选择
for (let pageNum = 1; pageNum <= Math.ceil(this.wellPagination.total / this.wellPagination.pageSize); pageNum++) {
const pageSelection = this.pageSelectionCache.get(pageNum) || []
allSelectedWells.push(...pageSelection)
}
this.wellSelection = allSelectedWells
console.log('最终选择状态:', this.wellSelection)
},
// 井号确定按钮点击
handleWellSubmit() {
if (this.wellSelection.length === 0) {
this.$message.warning('请选择邻井')
return
}
console.log('提交时的选择:', this.wellSelection)
// 邻井选择,用逗号隔开显示
this.formData.jhs = this.wellSelection.join(',')
console.log('赋值到邻井输入框:', this.formData.jhs)
this.$message.success(`邻井选择成功,已选择${this.wellSelection.length}个井号`)
this.wellDialogVisible = false
// 重新打开主弹窗并清除验证错误
this.$nextTick(() => {
this.dialogVisible = true
// 清除井号字段的验证错误
if (this.$refs.formRef) {
this.$refs.formRef.clearValidate('jhs')
}
})
},
// 井号选择弹窗取消按钮点击
handleWellCancel() {
this.wellDialogVisible = false
// 重新打开主弹窗
this.$nextTick(() => {
this.dialogVisible = true
})
},
// 弹窗关闭处理
handleDialogClose() {
// 弹窗关闭时不清空选择状态,保留选择直到确定提交
// this.wellSelection = []
// this.pageSelectionCache.clear()
},
// 主表格分页事件
handleMainSizeChange(size) {
this.mainPagination.pageSize = size;
this.mainPagination.pageNum = 1;
this.getList();
},
handleMainCurrentChange(page) {
this.mainPagination.pageNum = page;
this.getList();
},
formatTooltip(val) {
return val;
} }
}
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.djxx-container { .djxx-container {
padding: 15px; padding: 15px;
height: calc(100vh - 85px); height: calc(100vh - 85px);
overflow: hidden; overflow: hidden;
position: relative; position: relative;
.search-form { .search-form {
margin-bottom: 10px; margin-bottom: 10px;
} }
.el-table { .el-table {
margin-top: 10px; margin-top: 10px;
} }
} }
::v-deep .el-table--medium .el-table__cell { ::v-deep .el-table--medium .el-table__cell {
padding: 5px 0 !important; padding: 5px 0 !important;
} }
::v-deep.pagination-container { ::v-deep.pagination-container {
padding: 0px !important; padding: 0px !important;
margin: 0; margin: 0;
} }
</style> </style>
\ No newline at end of file
<template> <template>
<div class="drilling-chart-container" v-loading="loading" element-loading-text="加载中..." <div class="drilling-chart-container" v-loading="loading" element-loading-text="加载中..."
element-loading-background="rgba(255, 255, 255, 0.7)"> element-loading-background="rgba(255, 255, 255, 0.7)">
<div class="chart-wrapper"> <div>
<el-button type="primary" icon="el-icon-download" size="small" class="export-btn" @click="exportChart" <span class="well-label" style="margin-left: 10px">开次:</span>
:disabled="!myChart"> <el-select v-model="kc" style="width: 100px" size="mini" clearable placeholder="请选择">
导出图片 <el-option
</el-button> v-for="item in kcData"
<div id="drillingEfficiencyChartdj" class="chart"></div> :key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
<span class="well-label" style="margin-left: 10px">钻头尺寸:</span>
<el-input v-model="ztccs" style="width: 100px" clearable size="mini"></el-input>
<el-button type="primary" style="margin-left: 10px" size="mini" @click="getList">查询</el-button>
<el-button type="primary" icon="el-icon-download" size="mini" @click="exportChart"
:disabled="!myChart">
</el-button>
</div>
<div class="chart-wrapper">
<div id="drillingEfficiencyChartdj" class="chart"></div>
</div>
<!-- <div class="optimal-values">
<div class="optimal-item">
<span class="label">机速最优:</span>
<span class="value">{{ (chartData && chartData.jxzszy) || '--' }}</span>
</div> </div>
<!-- <div class="optimal-values"> <div class="optimal-item"></div>
<div class="optimal-item"> <span class="label">进尺最优:</span>
<span class="label">机速最优:</span> <span class="value">{{ (chartData && chartData.jczy) || '--' }}</span>
<span class="value">{{ (chartData && chartData.jxzszy) || '--' }}</span>
</div>
<div class="optimal-item"></div>
<span class="label">进尺最优:</span>
<span class="value">{{ (chartData && chartData.jczy) || '--' }}</span>
</div>
<div class="optimal-item">
<span class="label">综合最优:</span>
<span class="value">{{ (chartData && chartData.zhzy) || '--' }}</span>
</div>
</div> -->
<!-- 钻头优选表格 -->
<div class="table-section" v-if="tableData && tableData.length > 0">
<el-table :data="paginatedTableData" border stripe style="width: 100%" v-loading="tableLoading">
<el-table-column prop="jh" label="井号" align="center" min-width="120" show-overflow-tooltip />
<el-table-column prop="ztcc" label="钻头尺寸mm" align="center" min-width="120" show-overflow-tooltip />
<el-table-column prop="ztxh" label="钻头型号" align="center" min-width="150" show-overflow-tooltip />
<el-table-column prop="yxlx" label="优选类型" align="center" min-width="120" show-overflow-tooltip />
</el-table>
<!-- 分页组件 -->
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
:current-page="pagination.pageNum" :page-sizes="[10, 20, 50, 100]" :page-size="pagination.pageSize"
layout="total, sizes, prev, pager, next, jumper" :total="pagination.total"
style="margin-top: 10px; text-align: right;" />
</div> </div>
<div class="optimal-item">
<span class="label">综合最优:</span>
<span class="value">{{ (chartData && chartData.zhzy) || '--' }}</span>
</div>
</div> -->
<!-- 钻头优选表格 -->
<div class="table-section" v-if="tableData && tableData.length > 0">
<el-table :data="paginatedTableData" border stripe style="width: 100%" v-loading="tableLoading">
<el-table-column prop="jh" label="井号" align="center" min-width="120" show-overflow-tooltip/>
<el-table-column prop="ztcc" label="钻头尺寸mm" align="center" min-width="120" show-overflow-tooltip/>
<el-table-column prop="ztxh" label="钻头型号" align="center" min-width="150" show-overflow-tooltip/>
<el-table-column prop="yxlx" label="优选类型" align="center" min-width="120" show-overflow-tooltip/>
</el-table>
<!-- 分页组件 -->
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
:current-page="pagination.pageNum" :page-sizes="[10, 20, 50, 100]" :page-size="pagination.pageSize"
layout="total, sizes, prev, pager, next, jumper" :total="pagination.total"
style="margin-top: 10px; text-align: right;"/>
</div> </div>
</div>
</template> </template>
<script> <script>
import * as echarts from 'echarts'; import * as echarts from 'echarts';
import { getDjztqxt } from '@/api/optimization/initialization'; import {getDjztqxt} from '@/api/optimization/initialization';
export default { export default {
props: { props: {
jh: { jh: {
type: String, type: String,
required: true, required: true,
},
jhs: {
type: String,
required: true,
},
zbid: {
type: String,
required: true,
},
qk: {
type: String,
required: true,
},
ztcc: {
type: String,
required: true,
}
}, },
data() { jhs: {
return { type: String,
chartData: null, required: true,
myChart: null,
resizeHandler: null,
loading: false, // 新增loading状态
tableData: [], // 表格数据
tableLoading: false, // 表格loading状态
pagination: {
pageNum: 1,
pageSize: 20,
total: 0
}
};
}, },
mounted() { zbid: {
// 不在挂载时自动请求数据,等待父组件触发 loadData() type: String,
this.$once('hook:beforeDestroy', this.cleanup); required: true,
}, },
methods: { qk: {
// 供父组件调用 type: String,
loadData() { required: true,
this.getList(); },
}, ztcc: {
getList() { type: String,
const params = { zbid: this.zbid, ztccs: this.ztcc, qk: this.qk }; required: true,
this.loading = true; },
this.tableLoading = true; kcjs: {
getDjztqxt(params) type: String,
.then(res => { required: true,
console.log('接口返回数据:', res); },
this.chartData = res; ztccsjs: {
this.initChart(); type: String,
// 处理表格数据 required: true,
if (res && res.zyzt && Array.isArray(res.zyzt)) { }
this.tableData = res.zyzt; },
this.pagination.total = res.zyzt.length; data() {
this.pagination.pageNum = 1; return {
} else { chartData: null,
this.tableData = []; myChart: null,
this.pagination.total = 0; resizeHandler: null,
} loading: false, // 新增loading状态
}) tableData: [], // 表格数据
.catch(error => { tableLoading: false, // 表格loading状态
console.error('接口请求失败:', error); pagination: {
this.chartData = null; pageNum: 1,
this.tableData = []; pageSize: 20,
this.pagination.total = 0; total: 0
this.initChart(); },
}) kc: '',
.finally(() => { ztccs: '',
this.loading = false; kcData: [
this.tableLoading = false; {
}); label: '1',
value: '1',
}, {
label: '2',
value: '2',
}, {
label: '3',
value: '3',
}, {
label: '4',
value: '4',
}, {
label: '5',
value: '5',
}, },
]
};
},
created() {
this.kc=this.kcjs
this.ztccs=this.ztccsjs
},
mounted() {
// 不在挂载时自动请求数据,等待父组件触发 loadData()
this.$once('hook:beforeDestroy', this.cleanup);
},
methods: {
// 供父组件调用
loadData() {
this.getList();
},
getList() {
const params = {zbid: this.zbid, ztccs: this.ztcc, qk: this.qk,kc:this.kc}
this.loading = true;
this.tableLoading = true;
getDjztqxt(params)
.then(res => {
console.log('接口返回数据:', res);
this.chartData = res;
this.initChart();
// 处理表格数据
if (res && res.zyzt && Array.isArray(res.zyzt)) {
this.tableData = res.zyzt;
this.pagination.total = res.zyzt.length;
this.pagination.pageNum = 1;
} else {
this.tableData = [];
this.pagination.total = 0;
}
})
.catch(error => {
console.error('接口请求失败:', error);
this.chartData = null;
this.tableData = [];
this.pagination.total = 0;
this.initChart();
})
.finally(() => {
this.loading = false;
this.tableLoading = false;
});
},
initChart() { initChart() {
if (!this.chartData) { if (!this.chartData) {
const chartDom = document.getElementById('drillingEfficiencyChartdj'); const chartDom = document.getElementById('drillingEfficiencyChartdj');
if (chartDom && this.myChart) { if (chartDom && this.myChart) {
this.myChart.clear(); this.myChart.clear();
} }
return; return;
} }
const chartDom = document.getElementById('drillingEfficiencyChartdj'); const chartDom = document.getElementById('drillingEfficiencyChartdj');
if (!chartDom) { if (!chartDom) {
console.error('未找到图表容器'); console.error('未找到图表容器');
return; return;
} }
if (chartDom.offsetWidth === 0 || chartDom.offsetHeight === 0) { if (chartDom.offsetWidth === 0 || chartDom.offsetHeight === 0) {
console.log('容器尺寸为0,200ms后重试'); console.log('容器尺寸为0,200ms后重试');
setTimeout(() => this.initChart(), 200); setTimeout(() => this.initChart(), 200);
return; return;
} }
if (this.myChart) { if (this.myChart) {
this.myChart.dispose(); this.myChart.dispose();
} }
this.myChart = echarts.init(chartDom); this.myChart = echarts.init(chartDom);
// 解析接口数据(确保折线数据格式正确) // 解析接口数据(确保折线数据格式正确)
const { axisRange, scatterData, targetLineData, crosshair } = this.chartData; const {axisRange, scatterData, targetLineData, crosshair} = this.chartData;
// 数据顺序:[speed, depth, drillType, jh, cc] // 数据顺序:[speed, depth, drillType, jh, cc]
const scatter = scatterData.map(item => [item.speed, item.depth, item.drillType, item.jh, item.cc]); const scatter = scatterData.map(item => [item.speed, item.depth, item.drillType, item.jh, item.cc]);
// 折线数据必须为数组格式:[[钻速, 进尺], ...] // 折线数据必须为数组格式:[[钻速, 进尺], ...]
const targetLine = targetLineData.map(item => [item.speed, item.depth]); const targetLine = targetLineData.map(item => [item.speed, item.depth]);
const drillTypes = [...new Set(scatterData.map(item => item.drillType))]; const drillTypes = [...new Set(scatterData.map(item => item.drillType))];
const colorPalette = ['#3b82f6', '#10b981', '#f59e0b', '#ef4444', '#8b5cf6', '#14b8a6', '#ec4899', '#6366f1', '#f97316', '#0ea5e9']; const colorPalette = ['#3b82f6', '#10b981', '#f59e0b', '#ef4444', '#8b5cf6', '#14b8a6', '#ec4899', '#6366f1', '#f97316', '#0ea5e9'];
const typeColorMap = drillTypes.reduce((acc, type, index) => { const typeColorMap = drillTypes.reduce((acc, type, index) => {
acc[type] = colorPalette[index % colorPalette.length]; acc[type] = colorPalette[index % colorPalette.length];
return acc; return acc;
}, {}); }, {});
// 十字线及中心点配置 // 十字线及中心点配置
const crosshairLines = []; const crosshairLines = [];
const crosshairCenter = []; const crosshairCenter = [];
if (crosshair) { if (crosshair) {
crosshairLines.push({ crosshairLines.push({
name: '十字线', name: '十字线',
type: 'line', type: 'line',
data: [[crosshair.y - 10, crosshair.x], [crosshair.y + 10, crosshair.x]], data: [[crosshair.y - 10, crosshair.x], [crosshair.y + 10, crosshair.x]],
lineStyle: { color: 'black', width: 1, type: 'dashed' }, lineStyle: {color: 'black', width: 1, type: 'dashed'},
symbol: 'none', symbol: 'none',
tooltip: { show: false } // 十字线不显示tooltip tooltip: {show: false} // 十字线不显示tooltip
}); });
crosshairLines.push({ crosshairLines.push({
name: '十字线', name: '十字线',
type: 'line', type: 'line',
data: [[crosshair.y, crosshair.x - 500], [crosshair.y, crosshair.x + 500]], data: [[crosshair.y, crosshair.x - 500], [crosshair.y, crosshair.x + 500]],
lineStyle: { color: 'black', width: 1, type: 'dashed' }, lineStyle: {color: 'black', width: 1, type: 'dashed'},
symbol: 'none', symbol: 'none',
tooltip: { show: false } // 十字线不显示tooltip tooltip: {show: false} // 十字线不显示tooltip
}); });
crosshairCenter.push({ crosshairCenter.push({
name: '十字线中心', name: '十字线中心',
type: 'scatter', type: 'scatter',
data: [[crosshair.y, crosshair.x]], data: [[crosshair.y, crosshair.x]],
symbolSize: 12, symbolSize: 12,
itemStyle: { color: 'orange', borderColor: '#fff', borderWidth: 2 } itemStyle: {color: 'orange', borderColor: '#fff', borderWidth: 2}
}); });
} }
// 图表配置项(核心:坐标轴触发,确保折线悬浮显示) // 图表配置项(核心:坐标轴触发,确保折线悬浮显示)
const option = { const option = {
title: { text: '钻头钻进能效分析', left: 'center' }, title: {text: '钻头钻进能效分析', left: 'center'},
tooltip: { tooltip: {
trigger: 'axis', // 基于坐标轴触发(不依赖数据点) trigger: 'axis', // 基于坐标轴触发(不依赖数据点)
axisPointer: { axisPointer: {
type: 'line', // 显示轴线指示器,辅助定位折线数据点 type: 'line', // 显示轴线指示器,辅助定位折线数据点
snap: true // 强制吸附到最近的折线数据点 snap: true // 强制吸附到最近的折线数据点
}, },
formatter: (params) => { formatter: (params) => {
// 遍历所有系列数据,找到折线图的信息 // 遍历所有系列数据,找到折线图的信息
const lineData = params.find(p => p.seriesName === '优化曲线'); const lineData = params.find(p => p.seriesName === '优化曲线');
const scatterData = params.find(p => drillTypes.includes(p.seriesName)); const scatterData = params.find(p => drillTypes.includes(p.seriesName));
const centerData = params.find(p => p.seriesName === '十字线中心'); const centerData = params.find(p => p.seriesName === '十字线中心');
let result = ''; let result = '';
// 折线图数据(必显) // 折线图数据(必显)
// if (lineData) { // if (lineData) {
// result += `优化曲线<br>钻速:${lineData.data[0]} m/h<br>进尺:${lineData.data[1]}<br>`; // result += `优化曲线<br>钻速:${lineData.data[0]} m/h<br>进尺:${lineData.data[1]}<br>`;
// } // }
// 散点数据(如果鼠标在散点上) // 散点数据(如果鼠标在散点上)
if (scatterData) { if (scatterData) {
const [speed, depth, drillType, jh, cc] = scatterData.data; const [speed, depth, drillType, jh, cc] = scatterData.data;
result += `井号:${jh}<br>机械钻速m/h${speed} m/h<br>进尺m${depth}<br>钻头型号:${drillType}<br>钻头尺寸:${cc}`; result += `井号:${jh}<br>机械钻速m/h${speed} m/h<br>进尺m${depth}<br>钻头型号:${drillType}<br>钻头尺寸:${cc}`;
} }
// 中心点数据(如果鼠标在中心点上) // 中心点数据(如果鼠标在中心点上)
// if (centerData) { // if (centerData) {
// result += `均值<br>钻速:${centerData.data[0]} m/h<br>进尺:${centerData.data[1]}<br>`; // result += `均值<br>钻速:${centerData.data[0]} m/h<br>进尺:${centerData.data[1]}<br>`;
// } // }
return result; return result;
} }
}, },
legend: { legend: {
data: ['指标', '钻速均值', '进尺均值', '优化曲线',], data: ['指标', '钻速均值', '进尺均值', '优化曲线',],
top: '10%', top: '10%',
right: '5%' right: '5%'
}, },
grid: { grid: {
left: '2%', left: '2%',
right: '5%', right: '5%',
top: '15%', top: '15%',
bottom: '10%', bottom: '10%',
containLabel: true containLabel: true
}, },
xAxis: { xAxis: {
name: '钻速 (m/h)', name: '钻速 (m/h)',
type: 'value', type: 'value',
min: axisRange.xAxis.min, min: axisRange.xAxis.min,
max: axisRange.xAxis.max, max: axisRange.xAxis.max,
// interval: axisRange.xAxis.interval, // interval: axisRange.xAxis.interval,
axisLabel: { formatter: '{value} m/h' }, axisLabel: {formatter: '{value} m/h'},
nameLocation: 'center', nameLocation: 'center',
nameGap: 30, nameGap: 30,
axisTick: { show: true }, axisTick: {show: true},
axisLine: { show: true } axisLine: {show: true}
}, },
yAxis: { yAxis: {
name: '进尺m', name: '进尺m',
type: 'value', type: 'value',
min: axisRange.yAxis.min, min: axisRange.yAxis.min,
// interval: axisRange.yAxis.interval, // interval: axisRange.yAxis.interval,
nameLocation: 'center', nameLocation: 'center',
nameGap: 40, nameGap: 40,
axisTick: { show: true }, axisTick: {show: true},
axisLine: { show: true } axisLine: {show: true}
}, },
series: [ series: [
{ {
name: '优化曲线', name: '优化曲线',
type: 'line', type: 'line',
data: targetLine, // 确保数据正确 data: targetLine, // 确保数据正确
smooth: true, smooth: true,
// 彻底隐藏所有点(包括悬浮时) // 彻底隐藏所有点(包括悬浮时)
symbol: 'none', symbol: 'none',
showSymbol: false, showSymbol: false,
emphasis: { showSymbol: false }, emphasis: {showSymbol: false},
lineStyle: { color: 'red', width: 2 } lineStyle: {color: 'red', width: 2}
}, },
{ {
name: '钻速均值', name: '钻速均值',
type: 'line', type: 'line',
data: [[crosshair.x, axisRange.yAxis.min], [crosshair.x, axisRange.yAxis.max]], data: [[crosshair.x, axisRange.yAxis.min], [crosshair.x, axisRange.yAxis.max]],
lineStyle: { color: '#9eca7f', width: 2, type: 'dashed' }, lineStyle: {color: '#9eca7f', width: 2, type: 'dashed'},
symbol: 'none', symbol: 'none',
tooltip: { show: false } tooltip: {show: false}
}, },
{ {
name: '进尺均值', name: '进尺均值',
type: 'line', type: 'line',
data: [[crosshair.x - 500, crosshair.y], [crosshair.x + 500, crosshair.y]], data: [[crosshair.x - 500, crosshair.y], [crosshair.x + 500, crosshair.y]],
lineStyle: { color: '#f2ca6b', width: 2 }, lineStyle: {color: '#f2ca6b', width: 2},
symbol: 'none', symbol: 'none',
tooltip: { show: false } tooltip: {show: false}
}, },
...crosshairLines, ...crosshairLines,
...crosshairCenter, ...crosshairCenter,
...drillTypes.map(type => { ...drillTypes.map(type => {
const color = typeColorMap[type]; const color = typeColorMap[type];
return { return {
name: type, name: type,
type: 'scatter', type: 'scatter',
data: scatter.filter(item => item[2] === type), data: scatter.filter(item => item[2] === type),
symbolSize: 12, symbolSize: 12,
itemStyle: { itemStyle: {
color, color,
borderColor: color, borderColor: color,
borderWidth: 3, borderWidth: 3,
shadowColor: color, shadowColor: color,
shadowBlur: 8 shadowBlur: 8
}, },
label: { label: {
show: true, show: true,
position: 'top', position: 'top',
formatter: type, formatter: type,
fontSize: 10, fontSize: 10,
color color
} }
};
})
]
}; };
})
]
};
this.myChart.setOption(option); this.myChart.setOption(option);
this.resizeHandler = () => this.myChart.resize(); this.resizeHandler = () => this.myChart.resize();
window.addEventListener('resize', this.resizeHandler); window.addEventListener('resize', this.resizeHandler);
}, },
exportChart() { exportChart() {
if (!this.myChart) { if (!this.myChart) {
this.$message.warning('图表未初始化,无法导出'); this.$message.warning('图表未初始化,无法导出');
return; return;
} }
try { try {
// 获取图表的 base64 图片数据 // 获取图表的 base64 图片数据
const url = this.myChart.getDataURL({ const url = this.myChart.getDataURL({
type: 'png', type: 'png',
pixelRatio: 2, // 提高图片清晰度 pixelRatio: 2, // 提高图片清晰度
backgroundColor: '#fff' backgroundColor: '#fff'
}); });
// 创建下载链接
const link = document.createElement('a');
link.href = url;
link.download = `钻头钻进能效分析_${this.jh}_${new Date().getTime()}.png`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
this.$message.success('图片导出成功');
} catch (error) {
console.error('导出图片失败:', error);
this.$message.error('导出图片失败,请重试');
}
},
cleanup() { // 创建下载链接
if (this.myChart) { const link = document.createElement('a');
this.myChart.dispose(); link.href = url;
this.myChart = null; link.download = `钻头钻进能效分析_${this.jh}_${new Date().getTime()}.png`;
} document.body.appendChild(link);
if (this.resizeHandler) { link.click();
window.removeEventListener('resize', this.resizeHandler); document.body.removeChild(link);
this.resizeHandler = null;
}
},
// 分页大小改变 this.$message.success('图片导出成功');
handleSizeChange(size) { } catch (error) {
this.pagination.pageSize = size; console.error('导出图片失败:', error);
this.pagination.pageNum = 1; this.$message.error('导出图片失败,请重试');
}, }
},
// 当前页改变 cleanup() {
handleCurrentChange(page) { if (this.myChart) {
this.pagination.pageNum = page; this.myChart.dispose();
} this.myChart = null;
}
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
}, },
computed: {
// 分页后的表格数据 // 分页大小改变
paginatedTableData() { handleSizeChange(size) {
const start = (this.pagination.pageNum - 1) * this.pagination.pageSize; this.pagination.pageSize = size;
const end = start + this.pagination.pageSize; this.pagination.pageNum = 1;
return this.tableData.slice(start, end); },
}
// 当前页改变
handleCurrentChange(page) {
this.pagination.pageNum = page;
}
},
computed: {
// 分页后的表格数据
paginatedTableData() {
const start = (this.pagination.pageNum - 1) * this.pagination.pageSize;
const end = start + this.pagination.pageSize;
return this.tableData.slice(start, end);
} }
}
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.drilling-chart-container { .drilling-chart-container {
width: 100%; width: 100%;
height: 100%; height: 100%;
position: relative; position: relative;
padding: 20px; padding: 20px;
box-sizing: border-box; box-sizing: border-box;
} }
.optimal-values { .optimal-values {
position: absolute; position: absolute;
top: 10px; top: 10px;
left: 10px; left: 10px;
z-index: 10; z-index: 10;
background: linear-gradient(135deg, rgba(255, 255, 255, 0.95) 0%, rgba(248, 250, 252, 0.95) 100%); 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: 1px solid rgba(64, 158, 255, 0.15);
border-radius: 6px; border-radius: 6px;
padding: 6px 10px; 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); 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); backdrop-filter: blur(8px);
min-width: 250px; min-width: 250px;
max-width: 280px; max-width: 280px;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
word-wrap: break-word; word-wrap: break-word;
word-break: break-all; word-break: break-all;
white-space: normal; white-space: normal;
} }
.optimal-values:hover { .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); 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); transform: translateY(-2px);
border-color: rgba(64, 158, 255, 0.25); border-color: rgba(64, 158, 255, 0.25);
} }
.optimal-item { .optimal-item {
display: block; display: block;
margin-bottom: 4px; margin-bottom: 4px;
font-size: 13px; font-size: 13px;
padding: 2px 6px; padding: 2px 6px;
border-radius: 4px; border-radius: 4px;
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
position: relative; position: relative;
word-wrap: break-word; word-wrap: break-word;
word-break: break-all; word-break: break-all;
white-space: normal; white-space: normal;
text-align: left; text-align: left;
} }
.optimal-item:last-child { .optimal-item:last-child {
margin-bottom: 0; margin-bottom: 0;
} }
.optimal-item:hover { .optimal-item:hover {
background: linear-gradient(135deg, rgba(64, 158, 255, 0.08) 0%, rgba(103, 194, 58, 0.08) 100%); background: linear-gradient(135deg, rgba(64, 158, 255, 0.08) 0%, rgba(103, 194, 58, 0.08) 100%);
transform: translateX(2px); transform: translateX(2px);
box-shadow: 0 2px 8px rgba(64, 158, 255, 0.15); box-shadow: 0 2px 8px rgba(64, 158, 255, 0.15);
} }
.optimal-item::before { .optimal-item::before {
content: ''; content: '';
position: absolute; position: absolute;
left: 0; left: 0;
top: 50%; top: 50%;
transform: translateY(-50%); transform: translateY(-50%);
width: 3px; width: 3px;
height: 0; height: 0;
background: linear-gradient(135deg, #409eff 0%, #67c23a 100%); background: linear-gradient(135deg, #409eff 0%, #67c23a 100%);
border-radius: 2px; border-radius: 2px;
transition: height 0.2s ease; transition: height 0.2s ease;
} }
.optimal-item:hover::before { .optimal-item:hover::before {
height: 60%; height: 60%;
} }
.optimal-item .label { .optimal-item .label {
color: #5a5e66; color: #5a5e66;
font-weight: 500; font-weight: 500;
margin-right: 8px; margin-right: 8px;
font-size: 13px; font-size: 13px;
letter-spacing: 0.2px; letter-spacing: 0.2px;
opacity: 0.9; opacity: 0.9;
word-wrap: break-word; word-wrap: break-word;
word-break: break-all; word-break: break-all;
white-space: normal; white-space: normal;
display: inline; display: inline;
} }
.optimal-item .value { .optimal-item .value {
color: #2c3e50; color: #2c3e50;
font-weight: 700; font-weight: 700;
font-size: 13px; font-size: 13px;
background: linear-gradient(135deg, #409eff 0%, #67c23a 100%); background: linear-gradient(135deg, #409eff 0%, #67c23a 100%);
-webkit-background-clip: text; -webkit-background-clip: text;
-webkit-text-fill-color: transparent; -webkit-text-fill-color: transparent;
background-clip: text; background-clip: text;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
position: relative; position: relative;
word-wrap: break-word; word-wrap: break-word;
word-break: break-all; word-break: break-all;
white-space: normal; white-space: normal;
text-align: left; text-align: left;
display: inline; display: inline;
} }
.optimal-item .value::after { .optimal-item .value::after {
content: ''; content: '';
position: absolute; position: absolute;
bottom: -1px; bottom: -1px;
left: 0; left: 0;
width: 100%; width: 100%;
height: 1px; height: 1px;
background: linear-gradient(135deg, #409eff 0%, #67c23a 100%); background: linear-gradient(135deg, #409eff 0%, #67c23a 100%);
opacity: 0; opacity: 0;
transition: opacity 0.2s ease; transition: opacity 0.2s ease;
} }
.optimal-item:hover .value::after { .optimal-item:hover .value::after {
opacity: 0.3; opacity: 0.3;
} }
.chart-wrapper { .chart-wrapper {
position: relative; position: relative;
width: 100%; width: 100%;
height: calc(100vh - 220px); height: calc(100vh - 220px);
min-height: 600px; min-height: 600px;
} }
.chart { .chart {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.export-btn { .export-btn {
position: absolute; position: absolute;
top: 10px; top: 10px;
right: 10px; right: 10px;
z-index: 100; z-index: 100;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
} }
.table-section { .table-section {
margin-top: 20px; margin-top: 20px;
padding: 20px; padding: 20px;
background: #fff; background: #fff;
border-radius: 4px; border-radius: 4px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
} }
</style> </style>
\ No newline at end of file
<!-- 钻头使用情况 --> <!-- 钻头使用情况 -->
<template> <template>
<div class="app-container"> <div class="app-container">
<!-- 搜索区域 --> <!-- 搜索区域 -->
<div class="search-wrapper"> <div class="search-wrapper">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch"
label-width="68px"> label-width="68px">
<el-form-item> <el-form-item>
<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:jsha:export']">导出</el-button> v-hasPermi="['system:jsha:export']">导出
</el-form-item> </el-button>
</el-form> </el-form-item>
</div> </el-form>
</div>
<!-- 表格容器 --> <!-- 表格容器 -->
<div class="table-container"> <div class="table-container">
<!-- 主表格区域 --> <!-- 主表格区域 -->
<div class="main-table-wrapper" :class="{ 'with-detail': selectedRow }"> <div class="main-table-wrapper" :class="{ 'with-detail': selectedRow }">
<el-table border v-loading="loading" :data="jshaList" @selection-change="handleSelectionChange" <el-table border v-loading="loading" :data="jshaList" @selection-change="handleSelectionChange"
@row-click="handleRowClick" height="tableHeight" style="width: 100%"> @row-click="handleRowClick" height="tableHeight" style="width: 100%">
<el-table-column label="序号" align="center" prop="xh" width="90" show-overflow-tooltip fixed /> <el-table-column label="序号" align="center" prop="xh" width="90" show-overflow-tooltip fixed/>
<el-table-column label="井号" align="center" prop="jh" width="110" show-overflow-tooltip fixed /> <el-table-column label="井号" align="center" prop="jh" width="110" show-overflow-tooltip fixed/>
<el-table-column label="钻头序列号" align="center" prop="ztxlh" width="110" show-overflow-tooltip /> <el-table-column label="钻头序列号" align="center" prop="ztxlh" width="110" show-overflow-tooltip/>
<el-table-column label="尺寸mm" align="center" prop="cc" width="90" show-overflow-tooltip /> <el-table-column label="尺寸mm" align="center" prop="cc" width="90" show-overflow-tooltip/>
<el-table-column label="开始井深m" align="center" prop="qsjs" width="110" show-overflow-tooltip /> <el-table-column label="开始井深m" align="center" prop="qsjs" width="110" show-overflow-tooltip/>
<el-table-column label="结束井深m" align="center" prop="zzjs" width="110" show-overflow-tooltip /> <el-table-column label="结束井深m" align="center" prop="zzjs" width="110" show-overflow-tooltip/>
<el-table-column label="进尺m" align="center" prop="jc" width="90" show-overflow-tooltip /> <el-table-column label="进尺m" align="center" prop="jc" width="90" show-overflow-tooltip/>
<el-table-column label="机械钻速m/h" align="center" prop="jxzs" width="110" show-overflow-tooltip /> <el-table-column label="机械钻速m/h" align="center" prop="jxzs" width="110" show-overflow-tooltip/>
<el-table-column label="所钻地层" align="center" prop="szdc" width="110" show-overflow-tooltip /> <el-table-column label="所钻地层" align="center" prop="szdc" width="110" show-overflow-tooltip/>
<el-table-column label="厂家" align="center" prop="cj" width="90" show-overflow-tooltip /> <el-table-column label="厂家" align="center" prop="cj" width="90" show-overflow-tooltip/>
<el-table-column label="钻头型号" align="center" prop="ztxh" width="110" show-overflow-tooltip /> <el-table-column label="钻头型号" align="center" prop="ztxh" width="110" show-overflow-tooltip/>
<el-table-column label="IADC号" align="center" prop="iadc" width="110" show-overflow-tooltip /> <el-table-column label="IADC号" align="center" prop="iadc" width="110" show-overflow-tooltip/>
<el-table-column label="下井次数" align="center" prop="xjcs" width="110" show-overflow-tooltip /> <el-table-column label="下井次数" align="center" prop="xjcs" width="110" show-overflow-tooltip/>
<el-table-column label="类型" align="center" prop="lx" width="90" show-overflow-tooltip /> <el-table-column label="类型" align="center" prop="lx" width="90" show-overflow-tooltip/>
<el-table-column label="入井新度" align="center" prop="rjxd" width="110" show-overflow-tooltip /> <el-table-column label="入井新度" align="center" prop="rjxd" width="110" show-overflow-tooltip/>
<el-table-column label="出井新度" align="center" prop="cjxd" width="110" show-overflow-tooltip /> <el-table-column label="出井新度" align="center" prop="cjxd" width="110" show-overflow-tooltip/>
<el-table-column label="喷嘴直径1号" align="center" prop="pz1" width="110" show-overflow-tooltip /> <el-table-column label="喷嘴直径1号" align="center" prop="pz1" width="110" show-overflow-tooltip/>
<el-table-column label="喷嘴直径2号" align="center" prop="pz2" width="110" show-overflow-tooltip /> <el-table-column label="喷嘴直径2号" align="center" prop="pz2" width="110" show-overflow-tooltip/>
<el-table-column label="喷嘴直径3号" align="center" prop="pz3" width="110" show-overflow-tooltip /> <el-table-column label="喷嘴直径3号" align="center" prop="pz3" width="110" show-overflow-tooltip/>
<el-table-column label="喷嘴直径10号" align="center" prop="pz10" width="110" show-overflow-tooltip /> <el-table-column label="喷嘴直径10号" align="center" prop="pz10" width="110" show-overflow-tooltip/>
<el-table-column label="进尺工作时间合计" align="center" prop="jcsjhj" width="180" show-overflow-tooltip /> <el-table-column label="进尺工作时间合计" align="center" prop="jcsjhj" width="180" show-overflow-tooltip/>
<el-table-column label="进尺工作时间纯钻进" align="center" prop="jcsjczj" width="180" <el-table-column label="进尺工作时间纯钻进" align="center" prop="jcsjczj" width="180"
show-overflow-tooltip /> show-overflow-tooltip/>
<el-table-column label="进尺工作时间起下钻" align="center" prop="jcsjqxz" width="180" <el-table-column label="进尺工作时间起下钻" align="center" prop="jcsjqxz" width="180"
show-overflow-tooltip /> show-overflow-tooltip/>
<el-table-column label="进尺工作时间扩划眼" align="center" prop="jcsjkhy" width="180" <el-table-column label="进尺工作时间扩划眼" align="center" prop="jcsjkhy" width="180"
show-overflow-tooltip /> show-overflow-tooltip/>
<el-table-column label="钻压" align="center" prop="zy" width="90" show-overflow-tooltip /> <el-table-column label="钻压" align="center" prop="zy" width="90" show-overflow-tooltip/>
<el-table-column label="转速" align="center" prop="zs" width="90" show-overflow-tooltip /> <el-table-column label="转速" align="center" prop="zs" width="90" show-overflow-tooltip/>
<el-table-column label="缸径" align="center" prop="gj" width="90" show-overflow-tooltip /> <el-table-column label="缸径" align="center" prop="gj" width="90" show-overflow-tooltip/>
<el-table-column label="泵速" align="center" prop="bs" width="90" show-overflow-tooltip /> <el-table-column label="泵速" align="center" prop="bs" width="90" show-overflow-tooltip/>
<el-table-column label="排量" align="center" prop="pl" width="90" show-overflow-tooltip /> <el-table-column label="排量" align="center" prop="pl" width="90" show-overflow-tooltip/>
<el-table-column label="立管泵压" align="center" prop="lgby" width="110" show-overflow-tooltip /> <el-table-column label="立管泵压" align="center" prop="lgby" width="110" show-overflow-tooltip/>
</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, 40, 60, 80, 100]" @pagination="getList" :limit.sync="queryParams.pageSize" :page-sizes="[20, 40, 60, 80, 100]" @pagination="getList"
style="padding: 10px 0;" /> style="padding: 10px 0;"/>
</div> </div>
<!-- 详细数据表格区域 --> <!-- 详细数据表格区域 -->
<transition name="slide-fade"> <transition name="slide-fade">
<div v-if="selectedRow" class="detail-table-wrapper"> <div v-if="selectedRow" class="detail-table-wrapper">
<el-table :data="[selectedRow]" border style="width: 100%"> <el-table :data="[selectedRow]" border style="width: 100%">
<el-table-column label="刀翼总数" prop="tzxl01" align="center" min-width="10%" /> <el-table-column label="刀翼总数" prop="tzxl01" align="center" min-width="10%"/>
<el-table-column label="布齿密度" prop="tzxl02" align="center" min-width="10%" /> <el-table-column label="布齿密度" prop="tzxl02" align="center" min-width="10%"/>
<el-table-column label="切削齿尺寸mm" prop="tzxl03" align="center" min-width="10%" /> <el-table-column label="切削齿尺寸mm" prop="tzxl03" align="center" min-width="10%"/>
<el-table-column label="切削齿后倾角°" prop="tzxl04" align="center" min-width="10%" /> <el-table-column label="切削齿后倾角°" prop="tzxl04" align="center" min-width="10%"/>
<el-table-column label="冠部轮廓" prop="tzxl05" align="center" min-width="10%" /> <el-table-column label="冠部轮廓" prop="tzxl05" align="center" min-width="10%"/>
<el-table-column label="保径" prop="tzxl06" align="center" min-width="10%" /> <el-table-column label="保径" prop="tzxl06" align="center" min-width="10%"/>
</el-table> </el-table>
</div>
</transition>
</div> </div>
</transition>
</div>
</div> </div>
</template> </template>
<script> <script>
import { listDjJsha, listJsha, getJsha, delJsha, addJsha, updateJsha } from "@/api/system/jsha"; import {listDjJsha, listJsha, getJsha, delJsha, addJsha, updateJsha} from "@/api/system/jsha";
import { getBlockName, getQkxl } from "@/api/system/jsaa"; import {getBlockName, getQkxl} from "@/api/system/jsaa";
import { listTzsj } from "@/api/system/jsha"; import {listTzsj} from "@/api/system/jsha";
export default { export default {
name: "Jsha", name: "Jsha",
props: { props: {
jh: { jh: {
type: String, type: String,
default: '' default: ''
},
jhs: {
type: String,
default: ''
},
qk: {
type: String,
default: ''
},
ztcc: {
type: String,
default: ''
},
cw: {
type: String,
default: ''
}
}, },
data() { jhs: {
return { type: String,
// 区块下拉选项 default: ''
blockOptions: [],
// 遮罩层 - 初始设置为false,避免页面加载时就显示加载动画
loading: false,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 钻头数据表格数据
jshaList: [],
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
// 是否为编辑操作
isEdit: false,
// 标记是否已经初始化过数据,避免重复加载
dataInitialized: false,
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 20, // 修改回默认每页显示20条
qk: null,
ztcc: '',
jh: null,
jhs: null,
wjrqks: null,
wjrqjs: null,
ztxlh: null,
ztxh: null,
iadc: null,
xjcs: null,
cc: null,
lx: null,
cj: null,
rjxd: null,
cjxd: null,
pz1: null,
pz2: null,
pz3: null,
pz4: null,
pz5: null,
pz6: null,
pz7: null,
pz8: null,
pz9: null,
pz10: null,
qsjs: null,
zzjs: null,
szdc: null,
jc: null,
jxzs: null,
jcsjhj: null,
jcsjczj: null,
jcsjqxz: null,
jcsjkhy: null,
zy: null,
zs: null,
gj: null,
bs: null,
pl: null,
lgby: null,
ztyj: null,
hkyh: null,
cjl: null,
pssd: null,
ztsgl: null,
bsgl: null,
sfsdzg: null,
sfsdzt: null,
gllyl: null,
ycmsqk: null,
zcmsqk: null,
zjmsqk: null,
bz: null,
npc: null,
wpc: null,
mstz: null,
wz: null,
zc: null,
zj: null,
qzyy: null,
qttz: null,
nj: null,
zpzzs: null,
qsrq: null,
zzrq: null,
pzlx: null,
ztjg: null
},
// 表单参数
form: {},
// 表单校验
rules: {
jh: [
{ required: true, message: "井号不能为空", trigger: "blur" }
],
xh: [
{ required: true, message: "序号不能为空", trigger: "blur" }
],
cc: [
{ required: true, message: "尺寸不能为空", trigger: "blur" }
],
qsjs: [
{ required: true, message: "开始井深不能为空", trigger: "blur" }
],
zzjs: [
{ required: true, message: "结束井深不能为空", trigger: "blur" }
],
jc: [
{ required: true, message: "进尺不能为空", trigger: "blur" }
],
jxzs: [
{ required: true, message: "机械钻速不能为空", trigger: "blur" }
]
},
selectedRow: null, // 当前选中的行数据
tableHeight: null,
// 特征数据选项
t01Options: [],
t02Options: [],
t03Options: [],
t04Options: [],
t05Options: [],
t06Options: [],
formLoading: false, // 新增表单loading
};
}, },
computed: { qk: {
filteredBlockOptions() { type: String,
return this.blockOptions.filter(item => item && item.qk); default: ''
} },
ztcc: {
type: String,
default: ''
}, },
watch: { cw: {
jh: { type: String,
handler(newJh) { default: ''
if (newJh) { },
this.queryParams.jh = String(newJh).trim(); wjrqjsjs: {
// 添加错误处理 type: String,
try { default: ''
this.getList(); },
} catch (error) { wjrqksjs: {
console.error('监听jh变化时获取数据失败:', error); type: String,
} default: ''
} }
}, },
immediate: true data() {
}, return {
selectedRow: { // 区块下拉选项
handler(val) { blockOptions: [],
this.$nextTick(() => { // 遮罩层 - 初始设置为false,避免页面加载时就显示加载动画
const containerElement = document.querySelector('.app-container'); loading: false,
const searchElement = document.querySelector('.search-wrapper'); // 选中数组
ids: [],
// 检查元素是否存在 // 非单个禁用
if (!containerElement || !searchElement) { single: true,
return; // 非多个禁用
} multiple: true,
// 显示搜索条件
const containerHeight = containerElement.offsetHeight; showSearch: true,
const searchHeight = searchElement.offsetHeight; // 总条数
const paginationHeight = 50; // 分页器高度 total: 0,
// 钻头数据表格数据
if (val) { jshaList: [],
// 选中行时,减去详情表格高度 // 弹出层标题
this.tableHeight = containerHeight - searchHeight - paginationHeight - 50; title: "",
} else { // 是否显示弹出层
// 未选中行时,使用全部可用空间 open: false,
this.tableHeight = containerHeight - searchHeight - paginationHeight; // 是否为编辑操作
} isEdit: false,
}); // 标记是否已经初始化过数据,避免重复加载
}, dataInitialized: false,
immediate: true // 查询参数
queryParams: {
pageNum: 1,
pageSize: 20, // 修改回默认每页显示20条
qk: null,
ztcc: '',
jh: null,
jhs: null,
wjrqks: null,
wjrqjs: null,
ztxlh: null,
ztxh: null,
iadc: null,
xjcs: null,
cc: null,
lx: null,
cj: null,
rjxd: null,
cjxd: null,
pz1: null,
pz2: null,
pz3: null,
pz4: null,
pz5: null,
pz6: null,
pz7: null,
pz8: null,
pz9: null,
pz10: null,
qsjs: null,
zzjs: null,
szdc: null,
jc: null,
jxzs: null,
jcsjhj: null,
jcsjczj: null,
jcsjqxz: null,
jcsjkhy: null,
zy: null,
zs: null,
gj: null,
bs: null,
pl: null,
lgby: null,
ztyj: null,
hkyh: null,
cjl: null,
pssd: null,
ztsgl: null,
bsgl: null,
sfsdzg: null,
sfsdzt: null,
gllyl: null,
ycmsqk: null,
zcmsqk: null,
zjmsqk: null,
bz: null,
npc: null,
wpc: null,
mstz: null,
wz: null,
zc: null,
zj: null,
qzyy: null,
qttz: null,
nj: null,
zpzzs: null,
qsrq: null,
zzrq: null,
pzlx: null,
ztjg: null
},
// 表单参数
form: {},
// 表单校验
rules: {
jh: [
{required: true, message: "井号不能为空", trigger: "blur"}
],
xh: [
{required: true, message: "序号不能为空", trigger: "blur"}
],
cc: [
{required: true, message: "尺寸不能为空", trigger: "blur"}
],
qsjs: [
{required: true, message: "开始井深不能为空", trigger: "blur"}
],
zzjs: [
{required: true, message: "结束井深不能为空", trigger: "blur"}
],
jc: [
{required: true, message: "进尺不能为空", trigger: "blur"}
],
jxzs: [
{required: true, message: "机械钻速不能为空", trigger: "blur"}
]
},
selectedRow: null, // 当前选中的行数据
tableHeight: null,
// 特征数据选项
t01Options: [],
t02Options: [],
t03Options: [],
t04Options: [],
t05Options: [],
t06Options: [],
formLoading: false, // 新增表单loading
};
},
computed: {
filteredBlockOptions() {
return this.blockOptions.filter(item => item && item.qk);
}
},
watch: {
jh: {
handler(newJh) {
if (newJh) {
this.queryParams.jh = String(newJh).trim();
// 添加错误处理
try {
this.getList();
} catch (error) {
console.error('监听jh变化时获取数据失败:', error);
}
} }
},
immediate: true
}, },
mounted() { selectedRow: {
// 初始化表格高度 handler(val) {
this.$nextTick(() => { this.$nextTick(() => {
const containerElement = document.querySelector('.app-container'); const containerElement = document.querySelector('.app-container');
const searchElement = document.querySelector('.search-wrapper'); const searchElement = document.querySelector('.search-wrapper');
// 检查元素是否存在 // 检查元素是否存在
if (!containerElement || !searchElement) { if (!containerElement || !searchElement) {
return; return;
} }
const containerHeight = containerElement.offsetHeight; const containerHeight = containerElement.offsetHeight;
const searchHeight = searchElement.offsetHeight; const searchHeight = searchElement.offsetHeight;
const paginationHeight = 50; const paginationHeight = 50; // 分页器高度
if (val) {
// 选中行时,减去详情表格高度
this.tableHeight = containerHeight - searchHeight - paginationHeight - 50;
} else {
// 未选中行时,使用全部可用空间
this.tableHeight = containerHeight - searchHeight - paginationHeight; this.tableHeight = containerHeight - searchHeight - paginationHeight;
}
}); });
},
immediate: true
}
},
mounted() {
// 初始化表格高度
this.$nextTick(() => {
const containerElement = document.querySelector('.app-container');
const searchElement = document.querySelector('.search-wrapper');
// 检查元素是否存在
if (!containerElement || !searchElement) {
return;
}
const containerHeight = containerElement.offsetHeight;
const searchHeight = searchElement.offsetHeight;
const paginationHeight = 50;
this.tableHeight = containerHeight - searchHeight - paginationHeight;
});
// 添加窗口大小改变事件监听
window.addEventListener('resize', this.updateTableHeight);
},
beforeDestroy() {
// 移除事件监听
window.removeEventListener('resize', this.updateTableHeight);
},
created() {
// 如果传入了jh参数,设置到查询参数中
if (this.jh) {
this.queryParams.jh = this.jh;
}
// 如果传入了jhs参数,设置到查询参数中
if (this.jhs) {
this.queryParams.jhs = this.jhs;
}
// 只加载选项,不自动加载数据
// this.getList();
this.getBlockOptions();
this.getFeatureOptions();
},
methods: {
/** 获取区块下拉选项 */
getBlockOptions() {
getQkxl().then(response => {
this.blockOptions = response.data || [];
}).catch(error => {
console.error('获取区块选项失败:', error);
this.blockOptions = [];
});
},
/** 获取特征数据选项 */
getFeatureOptions() {
const featureTypes = [
{type: "刀翼总数", target: "t01Options"},
{type: "布齿密度", target: "t02Options"},
{type: "切削齿尺寸mm", target: "t03Options"},
{type: "切削齿后倾角°", target: "t04Options"},
{type: "冠部轮廓", target: "t05Options"},
{type: "保径", target: "t06Options"}
];
const promises = featureTypes.map(feature => {
// 确保参数是字符串类型
const params = {
tzdl: String(feature.type)
};
return listTzsj(params).then(response => ({
target: feature.target,
data: response.rows || []
})).catch(error => {
console.error(`获取特征数据失败 - ${feature.type}:`, error);
return {
target: feature.target,
data: []
};
});
});
Promise.all(promises)
.then(results => {
results.forEach(result => {
this[result.target] = result.data;
});
})
.catch(error => {
console.error('获取特征数据选项失败:', error);
this.$modal.msgError("获取特征数据选项失败");
});
},
/** 查询钻头数据列表 */
getList() {
this.loading = true;
// 确保参数类型正确,过滤掉空值
const params = {};
if (this.ztcc && this.ztcc.trim()) {
params.ztccs = String(this.ztcc).trim();
}
if (this.qk && this.qk.trim()) {
params.qk = String(this.qk).trim();
}
if (this.cw && this.cw.trim()) {
params.cw = String(this.cw).trim();
}
if(this.wjrqksjs){
params.wjrqks = String(this.wjrqksjs).trim();
}
if(this.wjrqjsjs){
params.wjrqjs = String(this.wjrqjsjs).trim();
}
// 添加窗口大小改变事件监听
window.addEventListener('resize', this.updateTableHeight); console.log('API参数:', params);
listDjJsha(params).then(response => {
this.jshaList = response.rows || [];
this.total = response.total || 0;
this.loading = false;
}).catch(error => {
console.error('获取钻头数据失败:', error);
this.$modal.msgError("获取钻头数据失败");
this.loading = false;
});
},
// 取消按钮
cancel() {
this.formLoading = false;
this.open = false;
this.reset();
}, },
beforeDestroy() { // 表单重置
// 移除事件监听 reset() {
window.removeEventListener('resize', this.updateTableHeight); this.formLoading = false;
this.form = {
jh: null,
xh: null,
ztxlh: null,
ztxh: null,
iadc: null,
xjcs: null,
cc: null,
lx: null,
cj: null,
rjxd: null,
cjxd: null,
pz1: null,
pz2: null,
pz3: null,
pz4: null,
pz5: null,
pz6: null,
pz7: null,
pz8: null,
pz9: null,
pz10: null,
qsjs: null,
zzjs: null,
szdc: null,
jc: null,
jxzs: null,
jcsjhj: null,
jcsjczj: null,
jcsjqxz: null,
jcsjkhy: null,
zy: null,
zs: null,
gj: null,
bs: null,
pl: null,
lgby: null,
ztyj: null,
hkyh: null,
cjl: null,
pssd: null,
ztsgl: null,
bsgl: null,
sfsdzg: null,
sfsdzt: null,
gllyl: null,
ycmsqk: null,
zcmsqk: null,
zjmsqk: null,
bz: null,
npc: null,
wpc: null,
mstz: null,
wz: null,
zc: null,
zj: null,
qzyy: null,
qttz: null,
nj: null,
zpzzs: null,
qsrq: null,
zzrq: null,
pzlx: null,
ztjg: null
};
this.resetForm("form");
}, },
created() { /** 搜索按钮操作 */
// 如果传入了jh参数,设置到查询参数中 handleQuery() {
if (this.jh) { this.queryParams.pageNum = 1;
this.queryParams.jh = this.jh; this.getList();
} },
// 如果传入了jhs参数,设置到查询参数中 /** 重置按钮操作 */
if (this.jhs) { resetQuery() {
this.queryParams.jhs = this.jhs; this.queryParams.wjrqks = '';
} this.queryParams.wjrqjs = '';
// 只加载选项,不自动加载数据 this.resetForm("queryForm");
// this.getList(); this.handleQuery();
this.getBlockOptions();
this.getFeatureOptions();
}, },
methods: { // 多选框选中数据
/** 获取区块下拉选项 */ handleSelectionChange(selection) {
getBlockOptions() { this.ids = selection.map(item => item.jh)
getQkxl().then(response => { this.single = selection.length !== 1
this.blockOptions = response.data || []; this.multiple = !selection.length
}).catch(error => { },
console.error('获取区块选项失败:', error); /** 新增按钮操作 */
this.blockOptions = []; handleAdd() {
this.reset();
this.isEdit = false;
this.open = true;
this.title = "添加钻头数据";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
this.isEdit = true;
const query = {
jh: row.jh,
xh: row.xh
}
getJsha(query).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改钻头数据";
});
},
/** 提交按钮 */
submitForm() {
this.formLoading = true;
this.$refs["form"].validate(valid => {
if (valid) {
if (this.isEdit) {
updateJsha(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
}).finally(() => {
this.formLoading = false;
}); });
}, } else {
/** 获取特征数据选项 */ addJsha(this.form).then(response => {
getFeatureOptions() { this.$modal.msgSuccess("新增成功");
const featureTypes = [ this.open = false;
{ type: "刀翼总数", target: "t01Options" }, this.getList();
{ type: "布齿密度", target: "t02Options" }, }).finally(() => {
{ type: "切削齿尺寸mm", target: "t03Options" }, this.formLoading = false;
{ type: "切削齿后倾角°", target: "t04Options" },
{ type: "冠部轮廓", target: "t05Options" },
{ type: "保径", target: "t06Options" }
];
const promises = featureTypes.map(feature => {
// 确保参数是字符串类型
const params = {
tzdl: String(feature.type)
};
return listTzsj(params).then(response => ({
target: feature.target,
data: response.rows || []
})).catch(error => {
console.error(`获取特征数据失败 - ${feature.type}:`, error);
return {
target: feature.target,
data: []
};
});
}); });
}
} else {
this.formLoading = false;
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const query = {
jh: row.jh,
xh: row.xh
};
this.$modal.confirm('是否确认删除钻头数据编号为"' + row.jh + '"的数据项?').then(function () {
return delJsha(query);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {
});
},
/** 导出按钮操作 */
handleExport() {
const exportParams = {
// ...this.queryParams,
ztcc: this.ztcc,
qk: this.qk
};
this.download('system/jshaPdc/export', exportParams, `jsha_${new Date().getTime()}.xlsx`)
},
Promise.all(promises) /** 处理行点击 */
.then(results => { async handleRowClick(row, column) {
results.forEach(result => { // 如果点击的是操作列,不执行任何操作
this[result.target] = result.data; if (column && column.property === 'operation') {
}); return;
}) }
.catch(error => {
console.error('获取特征数据选项失败:', error); try {
this.$modal.msgError("获取特征数据选项失败"); const query = {
}); jh: row.jh,
}, xh: row.xh
/** 查询钻头数据列表 */ }
getList() { const res = await getJsha(query);
this.loading = true; this.selectedRow = res.data;
} catch (error) {
// 确保参数类型正确,过滤掉空值 console.error('获取详细数据失败:', error);
const params = {}; this.selectedRow = null;
}
if (this.ztcc && this.ztcc.trim()) { },
params.ztccs = String(this.ztcc).trim(); updateTableHeight() {
} this.$nextTick(() => {
const containerElement = document.querySelector('.app-container');
if (this.qk && this.qk.trim()) { const searchElement = document.querySelector('.search-wrapper');
params.qk = String(this.qk).trim();
} // 检查元素是否存在
if (!containerElement || !searchElement) {
if (this.cw && this.cw.trim()) { return;
params.cw = String(this.cw).trim();
}
console.log('API参数:', params);
listDjJsha(params).then(response => {
this.jshaList = response.rows || [];
this.total = response.total || 0;
this.loading = false;
}).catch(error => {
console.error('获取钻头数据失败:', error);
this.$modal.msgError("获取钻头数据失败");
this.loading = false;
});
},
// 取消按钮
cancel() {
this.formLoading = false;
this.open = false;
this.reset();
},
// 表单重置
reset() {
this.formLoading = false;
this.form = {
jh: null,
xh: null,
ztxlh: null,
ztxh: null,
iadc: null,
xjcs: null,
cc: null,
lx: null,
cj: null,
rjxd: null,
cjxd: null,
pz1: null,
pz2: null,
pz3: null,
pz4: null,
pz5: null,
pz6: null,
pz7: null,
pz8: null,
pz9: null,
pz10: null,
qsjs: null,
zzjs: null,
szdc: null,
jc: null,
jxzs: null,
jcsjhj: null,
jcsjczj: null,
jcsjqxz: null,
jcsjkhy: null,
zy: null,
zs: null,
gj: null,
bs: null,
pl: null,
lgby: null,
ztyj: null,
hkyh: null,
cjl: null,
pssd: null,
ztsgl: null,
bsgl: null,
sfsdzg: null,
sfsdzt: null,
gllyl: null,
ycmsqk: null,
zcmsqk: null,
zjmsqk: null,
bz: null,
npc: null,
wpc: null,
mstz: null,
wz: null,
zc: null,
zj: null,
qzyy: null,
qttz: null,
nj: null,
zpzzs: null,
qsrq: null,
zzrq: null,
pzlx: null,
ztjg: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.queryParams.wjrqks = '';
this.queryParams.wjrqjs = '';
this.resetForm("queryForm");
this.handleQuery();
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.jh)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.isEdit = false;
this.open = true;
this.title = "添加钻头数据";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
this.isEdit = true;
const query = {
jh: row.jh,
xh: row.xh
}
getJsha(query).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改钻头数据";
});
},
/** 提交按钮 */
submitForm() {
this.formLoading = true;
this.$refs["form"].validate(valid => {
if (valid) {
if (this.isEdit) {
updateJsha(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
}).finally(() => {
this.formLoading = false;
});
} else {
addJsha(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
}).finally(() => {
this.formLoading = false;
});
}
} else {
this.formLoading = false;
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const query = {
jh: row.jh,
xh: row.xh
};
this.$modal.confirm('是否确认删除钻头数据编号为"' + row.jh + '"的数据项?').then(function () {
return delJsha(query);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => { });
},
/** 导出按钮操作 */
handleExport() {
const exportParams = {
// ...this.queryParams,
ztcc: this.ztcc,
qk: this.qk
};
this.download('system/jshaPdc/export', exportParams, `jsha_${new Date().getTime()}.xlsx`)
},
/** 处理行点击 */
async handleRowClick(row, column) {
// 如果点击的是操作列,不执行任何操作
if (column && column.property === 'operation') {
return;
}
try {
const query = {
jh: row.jh,
xh: row.xh
}
const res = await getJsha(query);
this.selectedRow = res.data;
} catch (error) {
console.error('获取详细数据失败:', error);
this.selectedRow = null;
}
},
updateTableHeight() {
this.$nextTick(() => {
const containerElement = document.querySelector('.app-container');
const searchElement = document.querySelector('.search-wrapper');
// 检查元素是否存在
if (!containerElement || !searchElement) {
return;
}
const containerHeight = containerElement.offsetHeight;
const searchHeight = searchElement.offsetHeight;
const paginationHeight = 50;
if (this.selectedRow) {
this.tableHeight = containerHeight - searchHeight - paginationHeight - 120;
} else {
this.tableHeight = containerHeight - searchHeight - paginationHeight;
}
});
},
/** 限制只能输入三位数字 */
handleNumberInput(value, key) {
// 如果值为空,直接返回
if (value === '') {
this.form[key] = '';
return;
}
// 移除非数字字符
value = value.toString().replace(/[^\d]/g, '');
// 限制长度为3位
if (value.length > 3) {
value = value.slice(0, 3);
}
// 更新表单数据
this.form[key] = value;
},
/** 限制只能输入数字且保留两位小数 */
handleDecimalInput(value, key) {
// 如果值为空,直接返回
if (value === '') {
this.form[key] = '';
return;
}
// 只允许输入数字和小数点
value = value.toString().replace(/[^\d.]/g, '');
// 保证只有一个小数点
const parts = value.split('.');
if (parts.length > 2) {
value = parts[0] + '.' + parts.slice(1).join('');
}
// 限制小数点后两位
if (parts.length === 2 && parts[1].length > 2) {
value = parts[0] + '.' + parts[1].slice(0, 2);
}
// 更新表单数据
this.form[key] = value;
},
/**
* 外部调用:加载数据
*/
loadData() {
// 每次激活都刷新列表
this.getList();
} }
const containerHeight = containerElement.offsetHeight;
const searchHeight = searchElement.offsetHeight;
const paginationHeight = 50;
if (this.selectedRow) {
this.tableHeight = containerHeight - searchHeight - paginationHeight - 120;
} else {
this.tableHeight = containerHeight - searchHeight - paginationHeight;
}
});
},
/** 限制只能输入三位数字 */
handleNumberInput(value, key) {
// 如果值为空,直接返回
if (value === '') {
this.form[key] = '';
return;
}
// 移除非数字字符
value = value.toString().replace(/[^\d]/g, '');
// 限制长度为3位
if (value.length > 3) {
value = value.slice(0, 3);
}
// 更新表单数据
this.form[key] = value;
},
/** 限制只能输入数字且保留两位小数 */
handleDecimalInput(value, key) {
// 如果值为空,直接返回
if (value === '') {
this.form[key] = '';
return;
}
// 只允许输入数字和小数点
value = value.toString().replace(/[^\d.]/g, '');
// 保证只有一个小数点
const parts = value.split('.');
if (parts.length > 2) {
value = parts[0] + '.' + parts.slice(1).join('');
}
// 限制小数点后两位
if (parts.length === 2 && parts[1].length > 2) {
value = parts[0] + '.' + parts[1].slice(0, 2);
}
// 更新表单数据
this.form[key] = value;
},
/**
* 外部调用:加载数据
*/
loadData() {
// 每次激活都刷新列表
this.getList();
} }
}
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.app-container { .app-container {
height: calc(100vh - 160px); height: calc(100vh - 160px);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
padding: 10px; padding: 10px;
box-sizing: border-box; box-sizing: border-box;
overflow: hidden; overflow: hidden;
} }
.search-wrapper { .search-wrapper {
flex: none; flex: none;
} }
.table-container { .table-container {
flex: 1; flex: 1;
position: relative; position: relative;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
overflow: hidden; overflow: hidden;
} }
.main-table-wrapper { .main-table-wrapper {
flex: 1; flex: 1;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
transition: all 0.3s ease; transition: all 0.3s ease;
overflow: hidden; overflow: hidden;
} }
.detail-table-wrapper { .detail-table-wrapper {
height: 75px; height: 75px;
width: 100%; width: 100%;
position: absolute; position: absolute;
bottom: 0; bottom: 0;
left: 0; left: 0;
background: #fff; background: #fff;
box-shadow: 0 -2px 4px rgba(0, 0, 0, 0.1); box-shadow: 0 -2px 4px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease; transition: all 0.3s ease;
z-index: 1; z-index: 1;
} }
.slide-fade-enter-active, .slide-fade-enter-active,
.slide-fade-leave-active { .slide-fade-leave-active {
transition: all 0.3s ease; transition: all 0.3s ease;
} }
.slide-fade-enter, .slide-fade-enter,
.slide-fade-leave-to { .slide-fade-leave-to {
transform: translateY(120px); transform: translateY(120px);
opacity: 0; opacity: 0;
} }
::v-deep .el-table { ::v-deep .el-table {
flex: 1; flex: 1;
} }
::v-deep .el-table__body-wrapper { ::v-deep .el-table__body-wrapper {
overflow-y: auto; overflow-y: auto;
} }
::v-deep .el-table__cell>.cell { ::v-deep .el-table__cell > .cell {
font-weight: normal; font-weight: normal;
} }
::v-deep .el-table--medium .el-table__cell { ::v-deep .el-table--medium .el-table__cell {
padding: 5px 0 !important; padding: 5px 0 !important;
} }
::v-deep.pagination-container { ::v-deep.pagination-container {
padding: 0px !important; padding: 0px !important;
margin: 0; margin: 0;
} }
.form-section { .form-section {
margin-bottom: 20px; margin-bottom: 20px;
.section-title { .section-title {
font-size: 16px; font-size: 16px;
font-weight: bold; font-weight: bold;
margin-bottom: 15px; margin-bottom: 15px;
padding-left: 10px; padding-left: 10px;
border-left: 3px solid #409EFF; border-left: 3px solid #409EFF;
} }
} }
::v-deep .el-form-item { ::v-deep .el-form-item {
margin-bottom: 18px; margin-bottom: 18px;
padding-right: 20px; padding-right: 20px;
} }
::v-deep .el-form-item { ::v-deep .el-form-item {
margin-bottom: 10px !important; margin-bottom: 10px !important;
} }
</style> </style>
<!-- 多井能效分析方案详情 --> <!-- 多井能效分析方案详情 -->
<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 ref="dataTableRef" :jh="queryParams.jh" :famc="queryParams.famc" :qk="queryParams.qk" <DataTable ref="dataTableRef" :jh="queryParams.jh" :famc="queryParams.famc" :qk="queryParams.qk"
:ztcc="queryParams.ztcc" :jhs="queryParams.jhs" :cw="queryParams.cw" /> :ztcc="queryParams.ztcc" :jhs="queryParams.jhs" :cw="queryParams.cw" :wjrqjsjs="queryParams.wjrqjs" :wjrqksjs="queryParams.wjrqks"/>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="曲线图形" name="curveGraph" lazy> <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" :kcjs="queryParams.kc"
</el-tab-pane> :ztccsjs="queryParams.ztccs"/>
</el-tabs> </el-tab-pane>
</div> </el-tabs>
</div>
</template> </template>
<script> <script>
...@@ -19,157 +20,164 @@ import DataTable from './components/DataTable.vue'; ...@@ -19,157 +20,164 @@ import DataTable from './components/DataTable.vue';
import CurveGraph from './components/CurveGraph.vue'; import CurveGraph from './components/CurveGraph.vue';
export default { export default {
name: "DjxxDetail", name: "DjxxDetail",
components: { components: {
DataTable, DataTable,
CurveGraph, CurveGraph,
}, },
data() { data() {
return { return {
// 当前激活的tab // 当前激活的tab
activeTab: 'dataTable', activeTab: 'dataTable',
// 显示搜索条件 // 显示搜索条件
showSearch: true, showSearch: true,
// 遮罩层 // 遮罩层
loading: false, loading: false,
// 选中数组 // 选中数组
ids: [], ids: [],
// 查询参数 // 查询参数
queryParams: { queryParams: {
jh: '', jh: '',
famc: '', famc: '',
qk: '', qk: '',
jhs: '', jhs: '',
ztcc: '', ztcc: '',
zbid: '', zbid: '',
cw: '' cw: '',
}, wjrqks: '',
// 标记是否是第一次进入页面 wjrqjs: ''
isFirstLoad: true },
}; // 标记是否是第一次进入页面
isFirstLoad: true
};
},
created() {
// 获取路由参数
console.log('详情页面created,完整路由对象:', this.$route);
const {jh, famc, qk, jhs, ztcc, zbid, cw, kc, ztccs,wjrqjs,wjrqks} = this.$route.params;
console.log('路由参数:', {jh, famc, qk, jhs, ztcc, zbid, cw, kc, ztccs,wjrqjs,wjrqks});
// 检查参数是否为空或undefined
// if (jh && jh !== 'undefined' && jh !== 'null') {
this.queryParams.jh = jh;
this.queryParams.famc = famc || '';
this.queryParams.qk = qk || '';
this.queryParams.jhs = jhs || '';
this.queryParams.ztcc = ztcc || ''
this.queryParams.zbid = zbid || ''
this.queryParams.cw = cw || ''
this.queryParams.kc = kc || '';
this.queryParams.ztccs = ztccs || '';
this.queryParams.wjrqks = wjrqks || '';
this.queryParams.wjrqjs = wjrqjs || '';
console.log('设置 queryParams:', this.queryParams);
// 强制默认展示“数据表格”Tab
this.activeTab = 'dataTable';
// } else {
// console.warn('未获取到有效的路由参数 jh,当前参数:', { jh, famc, qk, jhs,ztcc });
// }
// 确保第一次进入页面时不会自动初始化组件
console.log('页面初始化完成,等待用户点击tab');
},
mounted() {
// 页面挂载后,延迟加载第一个tab的数据,避免立即显示加载动画
this.$nextTick(() => {
// 延迟一小段时间再加载数据,让页面先渲染完成
setTimeout(() => {
if (this.activeTab === 'dataTable') {
this.$refs.dataTableRef && this.$refs.dataTableRef.loadData && this.$refs.dataTableRef.loadData();
}
}, 100);
});
},
methods: {
/** 搜索按钮操作 */
handleQuery() {
this.loading = true;
// 这里可以调用API进行数据查询
setTimeout(() => {
this.loading = false;
}, 1000);
}, },
created() {
// 获取路由参数 /** 移除记录按钮操作 */
console.log('详情页面created,完整路由对象:', this.$route); handleRemove() {
const { jh, famc, qk, jhs, ztcc, zbid, cw } = this.$route.params; if (this.ids.length === 0) {
console.log('路由参数:', { jh, famc, qk, jhs, ztcc, zbid, cw }); this.$message.warning('请选择要移除的记录');
return;
// 检查参数是否为空或undefined }
// if (jh && jh !== 'undefined' && jh !== 'null') { this.$modal.confirm('是否确认移除选中的记录?').then(() => {
this.queryParams.jh = jh; // 这里可以调用API进行删除操作
this.queryParams.famc = famc || ''; this.$modal.msgSuccess("移除成功");
this.queryParams.qk = qk || ''; }).catch(() => {
this.queryParams.jhs = jhs || ''; });
this.queryParams.ztcc = ztcc || ''
this.queryParams.zbid = zbid || ''
this.queryParams.cw = cw || ''
console.log('设置 queryParams:', this.queryParams);
// 强制默认展示“数据表格”Tab
this.activeTab = 'dataTable';
// } else {
// console.warn('未获取到有效的路由参数 jh,当前参数:', { jh, famc, qk, jhs,ztcc });
// }
// 确保第一次进入页面时不会自动初始化组件
console.log('页面初始化完成,等待用户点击tab');
}, },
mounted() {
// 页面挂载后,延迟加载第一个tab的数据,避免立即显示加载动画 // 多选框选中数据
this.$nextTick(() => { handleSelectionChange(selection) {
// 延迟一小段时间再加载数据,让页面先渲染完成 this.ids = selection.map(item => item.id);
setTimeout(() => {
if (this.activeTab === 'dataTable') {
this.$refs.dataTableRef && this.$refs.dataTableRef.loadData && this.$refs.dataTableRef.loadData();
}
}, 100);
});
}, },
methods: {
/** 搜索按钮操作 */ /** tab切换事件 */
handleQuery() { handleTabClick(tab) {
this.loading = true; console.log('切换到tab:', tab.name);
// 这里可以调用API进行数据查询 // 标记已经不是第一次加载
setTimeout(() => { this.isFirstLoad = false;
this.loading = false;
}, 1000); // 每次点击tab都调用loadData
}, if (tab.name === 'dataTable') {
this.$refs.dataTableRef && this.$refs.dataTableRef.loadData && this.$refs.dataTableRef.loadData();
/** 移除记录按钮操作 */ } else if (tab.name === 'curveGraph') {
handleRemove() { this.$refs.curveGraphRef && this.$refs.curveGraphRef.loadData && this.$refs.curveGraphRef.loadData();
if (this.ids.length === 0) { }
this.$message.warning('请选择要移除的记录');
return;
}
this.$modal.confirm('是否确认移除选中的记录?').then(() => {
// 这里可以调用API进行删除操作
this.$modal.msgSuccess("移除成功");
}).catch(() => { });
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id);
},
/** tab切换事件 */
handleTabClick(tab) {
console.log('切换到tab:', tab.name);
// 标记已经不是第一次加载
this.isFirstLoad = false;
// 每次点击tab都调用loadData
if (tab.name === 'dataTable') {
this.$refs.dataTableRef && this.$refs.dataTableRef.loadData && this.$refs.dataTableRef.loadData();
} else if (tab.name === 'curveGraph') {
this.$refs.curveGraphRef && this.$refs.curveGraphRef.loadData && this.$refs.curveGraphRef.loadData();
}
}
} }
}
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.app-container { .app-container {
padding: 10px; padding: 10px;
box-sizing: border-box; box-sizing: border-box;
} }
.tab-content { .tab-content {
padding: 5px 0; padding: 5px 0;
} }
.chart-container { .chart-container {
height: calc(100vh - 300px); height: calc(100vh - 300px);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
background-color: #f5f5f5; background-color: #f5f5f5;
border-radius: 4px; border-radius: 4px;
h3 { h3 {
color: #666; color: #666;
margin-bottom: 10px; margin-bottom: 10px;
} }
p { p {
color: #999; color: #999;
} }
} }
::v-deep .el-table__cell>.cell { ::v-deep .el-table__cell > .cell {
font-weight: normal; font-weight: normal;
} }
::v-deep .el-table--medium .el-table__cell { ::v-deep .el-table--medium .el-table__cell {
padding: 5px 0 !important; padding: 5px 0 !important;
} }
::v-deep .el-form-item { ::v-deep .el-form-item {
margin-bottom: 10px !important; margin-bottom: 10px !important;
} }
::v-deep .el-tabs__content { ::v-deep .el-tabs__content {
padding: 5px 0; padding: 5px 0;
margin-top: -10px; margin-top: -10px;
} }
</style> </style>
<!-- 多井钻头 --> <!-- 多井钻头 -->
<template> <template>
<div class="app-container"> <div class="app-container">
<!-- 搜索区域 --> <!-- 搜索区域 -->
<el-form :inline="true" :model="searchForm" class="search-form"> <el-form :inline="true" :model="searchForm" class="search-form">
<el-form-item label="区块" prop="qk"> <el-form-item label="区块" prop="qk">
<el-select v-model="searchForm.qk" placeholder="请选择区块" clearable filterable style="width: 150px;"> <el-select v-model="searchForm.qk" placeholder="请选择区块" clearable filterable style="width: 150px;">
<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" /> v-if="item && item.qk"/>
</el-select> </el-select>
</el-form-item>
<el-form-item label="钻头尺寸">
<el-input v-model="searchForm.ztcc" placeholder="请输入钻头信息" clearable></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="getList">搜索</el-button>
<el-button @click="resetSearch">重置</el-button>
<el-button type="success" @click="handleAdd">新增</el-button>
</el-form-item>
</el-form>
<!-- 表格区域 -->
<el-table :data="tableData" border stripe v-loading="loading" style="width: 100%; height: calc(100vh - 230px)">
<el-table-column prop="qk" label="区块" align="center" min-width="70" show-overflow-tooltip></el-table-column>
<el-table-column prop="famc" label="方案名称" align="center" min-width="100" show-overflow-tooltip sortable/>
<el-table-column prop="ztcc" label="钻头尺寸mm" align="center" min-width="160"
show-overflow-tooltip></el-table-column>
<el-table-column prop="dc" label="地层" align="center" min-width="120"
show-overflow-tooltip></el-table-column>
<el-table-column prop="yxzt" label="综合最优" align="center" min-width="155" show-overflow-tooltip sortable/>
<el-table-column prop="jczt" label="进尺最优" align="center" min-width="155" show-overflow-tooltip sortable/>
<el-table-column prop="jxzszt" label="转速最优" align="center" min-width="155" show-overflow-tooltip sortable/>
<el-table-column prop="bz" label="备注" align="center" min-width="180"
show-overflow-tooltip></el-table-column>
<el-table-column label="操作" width="160" align="center" fixed="right">
<template #default="scope">
<el-button size="mini" type="text" icon="el-icon-view" @click="handleView(scope.row)">查看</el-button>
<el-button type="text" size="mini" @click="handleEdit(scope.row)">编辑</el-button>
<el-button type="text" size="mini" @click="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<el-pagination style="margin-top: 10px; text-align: right;" v-model:current-page="pagination.currentPage"
v-model:page-size="pagination.pageSize" :page-sizes="[10, 20, 50, 100]" :total="pagination.total"
layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange"
@current-change="handleCurrentChange" background/>
<!-- 新增/编辑对话框 -->
<el-dialog :title="dialogTitle" width="900px" :close-on-click-modal="false" :visible.sync="dialogVisible">
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="140px">
<el-row>
<el-col :span="12">
<el-form-item label="方案名称" prop="famc">
<el-input v-model="formData.famc" placeholder="请输入方案名称"/>
</el-form-item> </el-form-item>
<el-form-item label="钻头尺寸"> </el-col>
<el-input v-model="searchForm.ztcc" placeholder="请输入钻头信息" clearable></el-input> <el-col :span="12">
<el-form-item label="区块" prop="qk">
<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"
v-if="item && item.qk" style="width: 100%;"/>
</el-select>
</el-form-item> </el-form-item>
<el-form-item> </el-col>
<el-button type="primary" @click="getList">搜索</el-button> </el-row>
<el-button @click="resetSearch">重置</el-button> <el-row>
<el-button type="success" @click="handleAdd">新增</el-button> <el-col :span="12">
<el-form-item label="完井时间" prop="wjsjks" required>
<el-date-picker v-model="formData.wjsjks" type="date" placeholder="选择开始日期"
style="width: 50%;"/>
<el-date-picker v-model="formData.wjsjjs" type="date" placeholder="选择结束日期"
style="width: 50%;"/>
</el-form-item> </el-form-item>
</el-form> </el-col>
<el-col :span="12">
<el-form-item label="层位" prop="cw">
<!-- 表格区域 --> <el-input v-if="!showCascader" v-model="formData.cw" readonly style="width: 100%;">
<el-table :data="tableData" border stripe v-loading="loading" style="width: 100%; height: calc(100vh - 230px)"> <template slot="append">
<el-table-column prop="qk" label="区块" align="center" min-width="70" show-overflow-tooltip></el-table-column> <el-button @click="openCascader">选择</el-button>
<el-table-column prop="famc" label="方案名称" align="center" min-width="100" show-overflow-tooltip sortable />
<el-table-column prop="ztcc" label="钻头尺寸mm" align="center" min-width="160"
show-overflow-tooltip></el-table-column>
<el-table-column prop="dc" label="地层" align="center" min-width="120"
show-overflow-tooltip></el-table-column>
<el-table-column prop="yxzt" label="综合最优" align="center" min-width="155" show-overflow-tooltip sortable />
<el-table-column prop="jczt" label="进尺最优" align="center" min-width="155" show-overflow-tooltip sortable />
<el-table-column prop="jxzszt" label="转速最优" align="center" min-width="155" show-overflow-tooltip sortable />
<el-table-column prop="bz" label="备注" align="center" min-width="180"
show-overflow-tooltip></el-table-column>
<el-table-column label="操作" width="160" align="center" fixed="right">
<template #default="scope">
<el-button size="mini" type="text" icon="el-icon-view" @click="handleView(scope.row)">查看</el-button>
<el-button type="text" size="mini" @click="handleEdit(scope.row)">编辑</el-button>
<el-button type="text" size="mini" @click="handleDelete(scope.row)">删除</el-button>
</template> </template>
</el-table-column> </el-input>
</el-table> <!-- 使用v-if来条件渲染el-cascader -->
<el-cascader v-if="showCascader" ref="cascader" v-model="cascaderValue" @change="change"
<!-- 分页 --> @click="handleCascaderClick" :options="mdcOptions" :props="mdc" placeholder="请选择层位"
<el-pagination style="margin-top: 10px; text-align: right;" v-model:current-page="pagination.currentPage" style="width: 200px;" popper-class="cascader-popper">
v-model:page-size="pagination.pageSize" :page-sizes="[10, 20, 50, 100]" :total="pagination.total" </el-cascader>
layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange" </el-form-item>
@current-change="handleCurrentChange" background /> </el-col>
</el-row>
<!-- 新增/编辑对话框 --> <el-row>
<el-dialog :title="dialogTitle" width="900px" :close-on-click-modal="false" :visible.sync="dialogVisible"> <el-col :span="12">
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="140px"> <el-form-item label="钻头尺寸mm" prop="ztcc">
<el-row> <el-input v-model="formData.ztcc" placeholder="请输入井眼尺寸"/>
<el-col :span="12">
<el-form-item label="方案名称" prop="famc"> <!-- <el-select v-model="formData.ztcc" multiple filterable allow-create default-first-option-->
<el-input v-model="formData.famc" placeholder="请输入方案名称" /> <!-- placeholder="请选择或输入钻头尺寸" style="width: 100%" :loading="ztxxLoading">-->
</el-form-item> <!-- <el-option v-for="item in ztxxOptions" :key="item.value" :label="item.label"-->
</el-col> <!-- :value="item.value"/>-->
<el-col :span="12"> <!-- </el-select>-->
<el-form-item label="区块" prop="qk"> </el-form-item>
<el-select v-model="formData.qk" placeholder="请选择区块名称" clearable filterable </el-col>
style="width: 100%;">
<el-option v-for="item in blockOptions" :key="item.qk" :label="item.qk" :value="item.qk" <el-col :span="12">
v-if="item && item.qk" style="width: 100%;" /> <el-form-item label="开次" prop="kc">
</el-select> <el-select v-model="formData.kc" filterable placeholder="请选择或输入钻头尺寸" style="width: 100%">
</el-form-item> <el-option v-for="item in kcData" :key="item.value" :label="item.label"
</el-col> :value="item.value"/>
</el-row> </el-select>
<el-row> </el-form-item>
<el-col :span="12"> </el-col>
<el-form-item label="完井时间" prop="wjsjks" required>
<el-date-picker v-model="formData.wjsjks" type="date" placeholder="选择开始日期" </el-row>
style="width: 50%;" /> <el-row>
<el-date-picker v-model="formData.wjsjjs" type="date" placeholder="选择结束日期" <el-col :span="12">
style="width: 50%;" /> <el-form-item label="进尺最优比例" prop="jcbl">
</el-form-item> <el-slider v-model="formData.jcbl" :max="1" :min="0" :step="0.1"
</el-col> :format-tooltip="formatTooltip"></el-slider>
<el-col :span="12">
<el-form-item label="层位" prop="cw"> </el-form-item>
<el-input v-if="!showCascader" v-model="formData.cw" readonly style="width: 100%;"> </el-col>
<template slot="append"> <el-col :span="12">
<el-button @click="openCascader">选择</el-button> <el-form-item label="机械钻速最优比例" prop="jxzsbl">
</template> <el-slider v-model="formData.jxzsbl" :max="1" :min="0" :step="0.1"
</el-input> :format-tooltip="formatTooltip"></el-slider>
<!-- 使用v-if来条件渲染el-cascader --> </el-form-item>
<el-cascader v-if="showCascader" ref="cascader" v-model="cascaderValue" @change="change" </el-col>
@click="handleCascaderClick" :options="mdcOptions" :props="mdc" placeholder="请选择层位"
style="width: 200px;" popper-class="cascader-popper"> </el-row>
</el-cascader> <el-row>
</el-form-item> <el-col :span="24">
</el-col> <el-form-item label="备注" prop="bz">
</el-row> <el-input v-model="formData.bz" type="textarea" :rows="3" placeholder="请输入备注信息"></el-input>
<el-row> </el-form-item>
<el-col :span="12"> </el-col>
<el-form-item label="钻头尺寸mm" prop="ztcc"> </el-row>
<el-select v-model="formData.ztcc" multiple filterable allow-create default-first-option </el-form>
placeholder="请选择或输入钻头尺寸" style="width: 100%" :loading="ztxxLoading"> <template #footer>
<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="jcbl">
<el-select v-model="formData.jcbl" placeholder="请选择进尺最优比例" clearable style="width: 100%;">
<el-option label="0.2" value="0.2" />
<el-option label="0.3" value="0.3" />
<el-option label="0.4" value="0.4" />
<el-option label="0.5" value="0.5" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="机械钻速最优比例" prop="jxzsbl">
<el-select v-model="formData.jxzsbl" placeholder="请选择机械钻速最优比例" clearable
style="width: 100%;">
<el-option label="0.2" value="0.2" />
<el-option label="0.3" value="0.3" />
<el-option label="0.4" value="0.4" />
<el-option label="0.5" value="0.5" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="备注" prop="bz">
<el-input v-model="formData.bz" type="textarea" :rows="3" placeholder="请输入备注信息"></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button> <el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button> <el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
</span> </span>
</template> </template>
</el-dialog> </el-dialog>
</div> </div>
</template> </template>
<script> <script>
import { getQkxl } from "@/api/system/jsaa"; import {getQkxl} from "@/api/system/jsaa";
import { getMdcByQkid } from "@/api/scientificDrill/schemeOptimization"; import {getMdcByQkid} from "@/api/scientificDrill/schemeOptimization";
import { selectZtccList, listDjzt, getDjzt, addDjzt, updateDjzt, delDjzt } from "@/api/system/djzt"; import {selectZtccList, listDjzt, getDjzt, addDjzt, updateDjzt, delDjzt} from "@/api/system/djzt";
export default { export default {
name: 'DjztIndex', name: 'DjztIndex',
data() { data() {
return { return {
mdcOptions: [], mdcOptions: [],
oilOptions: [], oilOptions: [],
mdc: { mdc: {
lazy: true, lazy: true,
lazyLoad: this.loadTreeNode, lazyLoad: this.loadTreeNode,
checkStrictly: true, // 允许选择任意级别的节点 checkStrictly: true, // 允许选择任意级别的节点
multiple: false, multiple: false,
expandTrigger: 'click', // 点击展开 expandTrigger: 'click', // 点击展开
emitPath: true, // 返回完整路径 emitPath: true, // 返回完整路径
maxLevel: 5 // 限制最多五级 maxLevel: 5 // 限制最多五级
}, },
cascaderValue: [],// 用于绑定 el-cascader 的 v-model cascaderValue: [],// 用于绑定 el-cascader 的 v-model
showCascader: false, showCascader: false,
blockOptions: [], blockOptions: [],
// 搜索表单 // 搜索表单
searchForm: { searchForm: {
qk: '', qk: '',
ztcc: '' ztcc: ''
}, },
// 表格数据 // 表格数据
tableData: [], tableData: [],
loading: false, loading: false,
// 分页 // 分页
pagination: { pagination: {
currentPage: 1, currentPage: 1,
pageSize: 10, pageSize: 10,
total: 0 total: 0
}, },
// 对话框 // 对话框
dialogVisible: false, dialogVisible: false,
dialogTitle: '新增', dialogTitle: '新增',
submitLoading: false, submitLoading: false,
// 表单数据 // 表单数据
formData: { formData: {
id: null, id: null,
qk: '', qk: '',
ztcc: [], kc: '',
cw: '', // 层位信息 ztcc: '',
cwid: null, // 层位ID cw: '', // 层位信息
mdcid: null, // 目的层ID cwid: null, // 层位ID
dzsdmc: '', // 地质时代名称 mdcid: null, // 目的层ID
wjsjks: this.getFiveYearsAgoDate(), // 完井开始日期默认前五年的今天 dzsdmc: '', // 地质时代名称
wjsjjs: this.getTodayDate(), // 完井结束日期默认今天 wjsjks: this.getFiveYearsAgoDate(), // 完井开始日期默认前五年的今天
bz: '', wjsjjs: this.getTodayDate(), // 完井结束日期默认今天
jcbl: '', // 进尺最优比例 bz: '',
jxzsbl: '' // 机械钻速最优比例 jcbl: 0.2, // 进尺最优比例
}, jxzsbl: 0.2 // 机械钻速最优比例
// 表单验证规则 },
formRules: { // 表单验证规则
famc: [ formRules: {
{ required: true, message: '请输入方案名称', trigger: 'blur' } famc: [
], {required: true, message: '请输入方案名称', trigger: 'blur'}
qk: [ ],
{ required: true, message: '请输入区块', trigger: 'blur' } qk: [
], {required: true, message: '请输入区块', trigger: 'blur'}
jcbl: [{ required: true, message: '请选择进尺最优比例', trigger: 'change' }], ],
jxzsbl: [{ required: true, message: '请选择机械钻速最优比例', trigger: 'change' }] jcbl: [{required: true, message: '请选择进尺最优比例', trigger: 'change'}],
}, jxzsbl: [{required: true, message: '请选择机械钻速最优比例', trigger: 'change'}]
// 钻头信息选项 },
ztxxOptions: [], // 钻头信息选项
// 钻头信息加载状态 ztxxOptions: [],
ztxxLoading: false, // 钻头信息加载状态
ztxxLoading: false,
kcData: [
{
label: '1',
value: '1',
}, {
label: '2',
value: '2',
}, {
label: '3',
value: '3',
}, {
label: '4',
value: '4',
}, {
label: '5',
value: '5',
},
]
}
},
watch: {
'formData.qk'() {
this.updateZtccOptionsIfReady()
},
'formData.wjsjks'() {
this.updateZtccOptionsIfReady()
},
'formData.wjsjjs'() {
this.updateZtccOptionsIfReady()
}
},
created() {
this.getBlockOptions();
this.getList();
},
mounted() {
this.getTableData()
},
methods: {
/** 获取今天的日期 */
getTodayDate() {
return new Date();
},
/** 获取前五年的今天日期 */
getFiveYearsAgoDate() {
const fiveYearsAgo = new Date();
fiveYearsAgo.setFullYear(fiveYearsAgo.getFullYear() - 5);
return fiveYearsAgo;
},
/** 格式化日期为字符串 */
formatDate(date) {
if (!date) return '';
const d = new Date(date);
const year = d.getFullYear();
const month = String(d.getMonth() + 1).padStart(2, '0');
const day = String(d.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
},
/** 查看按钮操作 */
async handleView(row) {
try {
const res = await getDjzt(row.id)
console.log(res, 55555);
if (res.code === 200) {
// 将获取到的详细信息传递给详情页面
const params = {
jh: res.data.jh || row.jh || '',
ztcc: row.ztcc || '',
qk: res.data.qk || row.qk || '',
zbid: res.data.id || row.id || '',
cw: row.cw || row.dc || '',
kc: res.data.kc || row.kc || '',
ztccs: res.data.ztcc || row.ztcc || '',
wjrqks: res.data.wjsjks || row.wjsjks || '',
wjrqjs: res.data.wjsjjs || row.wjsjjs || '',
};
console.log('params',params)
this.$router.push({
name: 'DjztDetail',
params: params
}).then(() => {
console.log('路由跳转成功');
}).catch(err => {
console.error('路由跳转失败:', err);
});
} else {
this.$message.error(res.msg || '获取详情失败')
} }
} catch (error) {
console.error('获取详情失败:', error)
this.$message.error('获取详情失败')
}
}, },
watch: { /** 初始化目的层选项 */
'formData.qk'() { initMdcOptions() {
this.updateZtccOptionsIfReady() // 加载根节点
}, const params = {
'formData.wjsjks'() { dclevel: 1,
this.updateZtccOptionsIfReady() pid: null,
}, };
'formData.wjsjjs'() {
this.updateZtccOptionsIfReady() getMdcByQkid(params).then(response => {
const options = response.data.map(item => ({
value: item.id,
label: item.mc,
leaf: false,
level: 1 // 设置根节点层级
}));
this.mdcOptions = options;
}).catch(error => {
console.error('初始化目的层选项失败:', error);
this.mdcOptions = [];
});
},
// 目的层相关方法
openCascader() {
this.showCascader = true;
// 确保级联选择器正确初始化
this.$nextTick(() => {
if (this.$refs.cascader) {
console.log('级联选择器已初始化');
// 设置初始值
if (this.formData.mdcid) {
this.cascaderValue = [this.formData.mdcid];
}
} }
});
}, },
created() { // 处理级联选择器点击
this.getBlockOptions(); handleCascaderClick() {
this.getList(); console.log('级联选择器被点击');
}, },
mounted() { change(val) {
this.getTableData() console.log('选择变化:', val); // 调试信息
if (val && val.length > 0) {
// 获取最后选择的节点值
const selectedValue = val[val.length - 1];
// 设置选中层的 id 到表单中
this.formData.mdcid = selectedValue;
// 直接通过级联选择器获取选中的标签
this.getSelectedLabel(val, selectedValue);
// 延迟关闭级联选择器,确保值已经设置
setTimeout(() => {
this.showCascader = false;
// 强制更新视图
this.$forceUpdate();
// 层位选择完成后尝试加载钻头尺寸
this.updateZtccOptionsIfReady();
}, 100);
} else {
this.showCascader = false;
}
}, },
methods: { // 获取选中节点的标签
/** 获取今天的日期 */ async getSelectedLabel(path, selectedValue) {
getTodayDate() { console.log('获取选中标签:', path, selectedValue);
return new Date();
}, // 从最后一级开始,逐级向上查找
/** 获取前五年的今天日期 */ for (let i = path.length - 1; i >= 0; i--) {
getFiveYearsAgoDate() { const currentValue = path[i];
const fiveYearsAgo = new Date(); const level = i + 1;
fiveYearsAgo.setFullYear(fiveYearsAgo.getFullYear() - 5);
return fiveYearsAgo; try {
}, const params = {
/** 格式化日期为字符串 */ dclevel: level,
formatDate(date) { pid: i === 0 ? null : path[i - 1]
if (!date) return ''; };
const d = new Date(date);
const year = d.getFullYear(); const response = await getMdcByQkid(params);
const month = String(d.getMonth() + 1).padStart(2, '0'); const nodes = response.data;
const day = String(d.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`; // 在当前级别中查找选中的节点
}, const selectedNode = nodes.find(item => item.id === currentValue);
/** 查看按钮操作 */
async handleView(row) { if (selectedNode) {
try { console.log('找到选中节点:', selectedNode);
const res = await getDjzt(row.id)
console.log(res, 55555); // 设置层位信息
if (res.code === 200) { this.formData.cw = selectedNode.mc; // 层位名称
// 将获取到的详细信息传递给详情页面 this.formData.cwid = selectedNode.id; // 层位ID
const params = {
jh: res.data.jh || row.jh || '', // 构建地质时代名称
ztcc: row.ztcc || '', this.buildDzsdmc(path, selectedNode);
qk: res.data.qk || row.qk || '',
zbid: res.data.id || row.id || '', this.$set(this.formData, 'cw', selectedNode.mc);
cw: row.cw || row.dc || '', this.$set(this.formData, 'cwid', selectedNode.id);
}; this.$set(this.formData, 'mdcid', selectedValue);
break;
this.$router.push({ }
name: 'DjztDetail', } catch (error) {
params: params console.error('获取节点信息失败:', error);
}).then(() => { }
console.log('路由跳转成功'); }
}).catch(err => { },
console.error('路由跳转失败:', err); // 构建地质时代名称
}); async buildDzsdmc(path, selectedNode) {
} else { console.log('构建地质时代名称:', path, selectedNode);
this.$message.error(res.msg || '获取详情失败')
}
} catch (error) {
console.error('获取详情失败:', error)
this.$message.error('获取详情失败')
}
},
/** 初始化目的层选项 */
initMdcOptions() {
// 加载根节点
const params = {
dclevel: 1,
pid: null,
};
getMdcByQkid(params).then(response => { if (path.length >= 2) {
const options = response.data.map(item => ({ try {
value: item.id, // 构建从盆地之后到选中节点之前的完整路径
label: item.mc, const eraPath = [];
leaf: false,
level: 1 // 设置根节点层级 // 从第二级开始(跳过盆地),到倒数第二级(选中节点的前一个)
})); for (let i = 1; i < path.length - 1; i++) {
this.mdcOptions = options; const currentValue = path[i];
}).catch(error => { const level = i + 1;
console.error('初始化目的层选项失败:', error); const pid = i === 1 ? path[0] : path[i - 1]; // 父级ID
this.mdcOptions = [];
});
},
// 目的层相关方法
openCascader() {
this.showCascader = true;
// 确保级联选择器正确初始化
this.$nextTick(() => {
if (this.$refs.cascader) {
console.log('级联选择器已初始化');
// 设置初始值
if (this.formData.mdcid) {
this.cascaderValue = [this.formData.mdcid];
}
}
});
},
// 处理级联选择器点击
handleCascaderClick() {
console.log('级联选择器被点击');
},
change(val) {
console.log('选择变化:', val); // 调试信息
if (val && val.length > 0) {
// 获取最后选择的节点值
const selectedValue = val[val.length - 1];
// 设置选中层的 id 到表单中
this.formData.mdcid = selectedValue;
// 直接通过级联选择器获取选中的标签
this.getSelectedLabel(val, selectedValue);
// 延迟关闭级联选择器,确保值已经设置
setTimeout(() => {
this.showCascader = false;
// 强制更新视图
this.$forceUpdate();
// 层位选择完成后尝试加载钻头尺寸
this.updateZtccOptionsIfReady();
}, 100);
} else {
this.showCascader = false;
}
},
// 获取选中节点的标签
async getSelectedLabel(path, selectedValue) {
console.log('获取选中标签:', path, selectedValue);
// 从最后一级开始,逐级向上查找
for (let i = path.length - 1; i >= 0; i--) {
const currentValue = path[i];
const level = i + 1;
try {
const params = {
dclevel: level,
pid: i === 0 ? null : path[i - 1]
};
const response = await getMdcByQkid(params);
const nodes = response.data;
// 在当前级别中查找选中的节点
const selectedNode = nodes.find(item => item.id === currentValue);
if (selectedNode) {
console.log('找到选中节点:', selectedNode);
// 设置层位信息
this.formData.cw = selectedNode.mc; // 层位名称
this.formData.cwid = selectedNode.id; // 层位ID
// 构建地质时代名称
this.buildDzsdmc(path, selectedNode);
this.$set(this.formData, 'cw', selectedNode.mc);
this.$set(this.formData, 'cwid', selectedNode.id);
this.$set(this.formData, 'mdcid', selectedValue);
break;
}
} catch (error) {
console.error('获取节点信息失败:', error);
}
}
},
// 构建地质时代名称
async buildDzsdmc(path, selectedNode) {
console.log('构建地质时代名称:', path, selectedNode);
if (path.length >= 2) {
try {
// 构建从盆地之后到选中节点之前的完整路径
const eraPath = [];
// 从第二级开始(跳过盆地),到倒数第二级(选中节点的前一个)
for (let i = 1; i < path.length - 1; i++) {
const currentValue = path[i];
const level = i + 1;
const pid = i === 1 ? path[0] : path[i - 1]; // 父级ID
const params = {
dclevel: level,
pid: pid
};
const response = await getMdcByQkid(params);
const nodes = response.data;
// 找到当前级别的节点
const currentNode = nodes.find(item => item.id === currentValue);
if (currentNode) {
eraPath.push(currentNode.mc);
}
}
// 构建地质时代名称:用/连接所有级别
const dzsdmc = eraPath.join('/');
console.log('构建的地质时代名称:', dzsdmc);
this.formData.dzsdmc = dzsdmc;
this.$set(this.formData, 'dzsdmc', dzsdmc);
} catch (error) {
console.error('构建地质时代名称失败:', error);
}
}
},
loadTreeNode(node, resolve) {
// 检查是否已达到最大层级(5级)
if (node.level >= 5) {
console.log('已达到最大层级,不再加载子节点');
resolve([]);
return;
}
const params = { const params = {
dclevel: node.level + 1, dclevel: level,
pid: node.value, pid: pid
}; };
console.log('加载节点参数:', params); // 调试信息
// 发起请求获取节点数据
getMdcByQkid(params).then(response => {
const oilOptions = response.data; // 获取到的数据
console.log('加载节点数据:', oilOptions); // 调试信息
if (Array.isArray(oilOptions) && oilOptions.length > 0) {
// 将数据转换为符合 Cascader 要求的格式
const nodes = oilOptions.map(item => ({
value: item.id,
label: item.mc,
leaf: node.level + 1 >= 5, // 第五级设置为叶子节点,不允许继续展开
level: node.level + 1 // 设置节点层级
}));
console.log('转换后的节点:', nodes); // 调试信息
resolve(nodes);
} else {
// 如果没有数据,返回空数组
console.log('没有找到子节点数据');
resolve([]);
}
}).catch(error => {
// 处理请求失败的情况
console.error('加载节点数据失败:', error);
resolve([]);
});
},
/** 获取钻头信息下拉选项 */
getZtxxOptions(queryParams) {
this.ztxxLoading = true; // 开始加载
selectZtccList(queryParams).then(response => {
if (response.code === 200 && response.data && Array.isArray(response.data)) {
this.ztxxOptions = response.data.map(item => ({
value: item,
label: item
}))
} else {
this.ztxxOptions = []
}
}).catch(error => {
console.error('获取钻头信息选项失败:', error)
this.ztxxOptions = []
}).finally(() => {
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() {
this.loading = true
try {
const params = {
pageNum: this.pagination.currentPage,
pageSize: this.pagination.pageSize,
...this.searchForm
}
const res = await listDjzt(params)
if (res.code === 200) {
this.tableData = res.rows || []
this.pagination.total = res.total || 0
} else {
this.$message.error(res.msg || '获取数据失败')
}
} catch (error) {
console.error('获取数据失败:', error)
this.$message.error('获取数据失败')
} finally {
this.loading = false
}
},
/** 获取区块下拉选项 */
getBlockOptions() {
getQkxl().then(response => {
// 过滤掉无效的选项
this.blockOptions = response.data.filter(item => item && item.qk);
});
},
// 搜索 const response = await getMdcByQkid(params);
getList() { const nodes = response.data;
this.pagination.currentPage = 1
this.getTableData()
},
// 重置搜索 // 找到当前级别的节点
resetSearch() { const currentNode = nodes.find(item => item.id === currentValue);
this.searchForm = {
qk: '',
ztcc: ''
}
this.getList()
this.resetForm("formData");
this.showCascader = false;
this.cascaderValue = []; // 重置 cascaderValue
this.ztxxOptions = []; // 清空钻头信息选项,等待条件满足后再加载
},
// 新增 if (currentNode) {
handleAdd() { eraPath.push(currentNode.mc);
this.dialogTitle = '新增'
this.formData = {
id: null,
qk: '',
ztcc: [],
cw: '', // 层位信息
cwid: null, // 层位ID
mdcid: null, // 目的层ID
dzsdmc: '', // 地质时代名称
wjsjks: this.getFiveYearsAgoDate(),
wjsjjs: this.getTodayDate(),
bz: '',
jcbl: '', // 进尺最优比例
jxzsbl: '' // 机械钻速最优比例
} }
this.dialogVisible = true }
// 新增打开时尝试基于默认年份加载(需等区块与层位选择后)
this.ztxxOptions = [] // 构建地质时代名称:用/连接所有级别
}, const dzsdmc = eraPath.join('/');
console.log('构建的地质时代名称:', dzsdmc);
this.formData.dzsdmc = dzsdmc;
this.$set(this.formData, 'dzsdmc', dzsdmc);
} catch (error) {
console.error('构建地质时代名称失败:', error);
}
}
},
loadTreeNode(node, resolve) {
// 检查是否已达到最大层级(5级)
if (node.level >= 5) {
console.log('已达到最大层级,不再加载子节点');
resolve([]);
return;
}
const params = {
dclevel: node.level + 1,
pid: node.value,
};
console.log('加载节点参数:', params); // 调试信息
// 发起请求获取节点数据
getMdcByQkid(params).then(response => {
const oilOptions = response.data; // 获取到的数据
console.log('加载节点数据:', oilOptions); // 调试信息
if (Array.isArray(oilOptions) && oilOptions.length > 0) {
// 将数据转换为符合 Cascader 要求的格式
const nodes = oilOptions.map(item => ({
value: item.id,
label: item.mc,
leaf: node.level + 1 >= 5, // 第五级设置为叶子节点,不允许继续展开
level: node.level + 1 // 设置节点层级
}));
console.log('转换后的节点:', nodes); // 调试信息
resolve(nodes);
} else {
// 如果没有数据,返回空数组
console.log('没有找到子节点数据');
resolve([]);
}
}).catch(error => {
// 处理请求失败的情况
console.error('加载节点数据失败:', error);
resolve([]);
});
},
/** 获取钻头信息下拉选项 */
getZtxxOptions(queryParams) {
this.ztxxLoading = true; // 开始加载
selectZtccList(queryParams).then(response => {
if (response.code === 200 && response.data && Array.isArray(response.data)) {
this.ztxxOptions = response.data.map(item => ({
value: item,
label: item
}))
} else {
this.ztxxOptions = []
}
}).catch(error => {
console.error('获取钻头信息选项失败:', error)
this.ztxxOptions = []
}).finally(() => {
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() {
this.loading = true
try {
const params = {
pageNum: this.pagination.currentPage,
pageSize: this.pagination.pageSize,
...this.searchForm
}
// 编辑 const res = await listDjzt(params)
handleEdit(row) {
this.dialogTitle = '编辑'
this.formData = {
id: row.id,
qk: row.qk,
ztcc: Array.isArray(row.ztcc) ? row.ztcc : (row.ztcc ? row.ztcc.split(',') : []),
cw: row.cw || row.dc || '', // 层位信息
cwid: row.cwid || null, // 层位ID
mdcid: row.mdcid || null, // 目的层ID
dzsdmc: row.dzsdmc || '', // 地质时代名称
wjsjks: row.wjsjks ? new Date(row.wjsjks) : this.getFiveYearsAgoDate(),
wjsjjs: row.wjsjjs ? new Date(row.wjsjjs) : this.getTodayDate(),
bz: row.bz,
famc: row.famc,
jcbl: row.jcbl || '', // 进尺最优比例
jxzsbl: row.jxzsbl || '' // 机械钻速最优比例
}
this.dialogVisible = true
// 编辑时若条件已满足,立即加载钻头尺寸
this.updateZtccOptionsIfReady()
},
// 删除 if (res.code === 200) {
handleDelete(row) { this.tableData = res.rows || []
this.$confirm('确认删除该记录吗?', '提示', { this.pagination.total = res.total || 0
confirmButtonText: '确定', } else {
cancelButtonText: '取消', this.$message.error(res.msg || '获取数据失败')
type: 'warning' }
}).then(async () => { } catch (error) {
try { console.error('获取数据失败:', error)
const res = await delDjzt(row.id) this.$message.error('获取数据失败')
} finally {
if (res.code === 200) { this.loading = false
this.$message.success('删除成功') }
this.getTableData() },
} else { /** 获取区块下拉选项 */
this.$message.error(res.msg || '删除失败') getBlockOptions() {
} getQkxl().then(response => {
} catch (error) { // 过滤掉无效的选项
console.error('删除失败:', error) this.blockOptions = response.data.filter(item => item && item.qk);
this.$message.error('删除失败') });
} },
}).catch(() => { })
},
// 提交表单 // 搜索
async handleSubmit() { getList() {
try { this.pagination.currentPage = 1
await this.$refs.formRef.validate() this.getTableData()
this.submitLoading = true },
// 准备提交数据,将数组转换为字符串,将Date对象转换为字符串
const submitData = {
...this.formData,
ztcc: Array.isArray(this.formData.ztcc) ? this.formData.ztcc.join(',') : this.formData.ztcc,
dc: this.formData.cw || '', // 使用层位信息作为地层
cw: this.formData.cw || '', // 保留层位信息
cwid: this.formData.cwid || null,
mdcid: this.formData.mdcid || null,
dzsdmc: this.formData.dzsdmc || '',
wjsjks: this.formData.wjsjks instanceof Date ? this.formatDate(this.formData.wjsjks) : this.formData.wjsjks,
wjsjjs: this.formData.wjsjjs instanceof Date ? this.formatDate(this.formData.wjsjjs) : this.formData.wjsjjs
}
const api = this.formData.id ? updateDjzt : addDjzt
const res = await api(submitData)
if (res.code === 200) {
this.$message.success(this.formData.id ? '更新成功' : '新增成功')
this.dialogVisible = false
this.getTableData()
} else {
this.$message.error(res.msg || '操作失败')
}
} catch (error) {
console.error('操作失败:', error)
if (error !== false) {
this.$message.error('操作失败')
}
} finally {
this.submitLoading = false
}
},
// 分页大小改变 // 重置搜索
handleSizeChange(val) { resetSearch() {
this.pagination.pageSize = val this.searchForm = {
this.getTableData() qk: '',
}, ztcc: ''
}
this.getList()
this.resetForm("formData");
this.showCascader = false;
this.cascaderValue = []; // 重置 cascaderValue
this.ztxxOptions = []; // 清空钻头信息选项,等待条件满足后再加载
},
// 当前页改变 // 新增
handleCurrentChange(val) { handleAdd() {
this.pagination.currentPage = val this.dialogTitle = '新增'
this.formData = {
id: null,
qk: '',
kc: '',
ztcc: '',
cw: '', // 层位信息
cwid: null, // 层位ID
mdcid: null, // 目的层ID
dzsdmc: '', // 地质时代名称
wjsjks: this.getFiveYearsAgoDate(),
wjsjjs: this.getTodayDate(),
bz: '',
jcbl: 0.2, // 进尺最优比例
jxzsbl: 0.2 // 机械钻速最优比例
}
this.dialogVisible = true
// 新增打开时尝试基于默认年份加载(需等区块与层位选择后)
this.ztxxOptions = []
},
// 编辑
handleEdit(row) {
this.dialogTitle = '编辑'
this.formData = {
id: row.id,
qk: row.qk,
kc: row.kc,
// ztcc: Array.isArray(row.ztcc) ? row.ztcc : (row.ztcc ? row.ztcc.split(',') : []),
ztcc: row.ztcc,
cw: row.cw || row.dc || '', // 层位信息
cwid: row.cwid || null, // 层位ID
mdcid: row.mdcid || null, // 目的层ID
dzsdmc: row.dzsdmc || '', // 地质时代名称
wjsjks: row.wjsjks ? new Date(row.wjsjks) : this.getFiveYearsAgoDate(),
wjsjjs: row.wjsjjs ? new Date(row.wjsjjs) : this.getTodayDate(),
bz: row.bz,
famc: row.famc,
jcbl: row.jcbl || '', // 进尺最优比例
jxzsbl: row.jxzsbl || '' // 机械钻速最优比例
}
this.dialogVisible = true
// 编辑时若条件已满足,立即加载钻头尺寸
this.updateZtccOptionsIfReady()
},
// 删除
handleDelete(row) {
this.$confirm('确认删除该记录吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
try {
const res = await delDjzt(row.id)
if (res.code === 200) {
this.$message.success('删除成功')
this.getTableData() this.getTableData()
}, } else {
this.$message.error(res.msg || '删除失败')
}
} catch (error) {
console.error('删除失败:', error)
this.$message.error('删除失败')
}
}).catch(() => {
})
},
// 表单重置 // 提交表单
resetForm(refName) { async handleSubmit() {
if (this.$refs[refName]) { try {
this.$refs[refName].resetFields(); await this.$refs.formRef.validate()
} this.submitLoading = true
// 准备提交数据,将数组转换为字符串,将Date对象转换为字符串
const submitData = {
...this.formData,
// ztcc: Array.isArray(this.formData.ztcc) ? this.formData.ztcc.join(',') : this.formData.ztcc,
ztcc: this.formData.ztcc,
dc: this.formData.cw || '', // 使用层位信息作为地层
cw: this.formData.cw || '', // 保留层位信息
cwid: this.formData.cwid || null,
mdcid: this.formData.mdcid || null,
dzsdmc: this.formData.dzsdmc || '',
wjsjks: this.formData.wjsjks instanceof Date ? this.formatDate(this.formData.wjsjks) : this.formData.wjsjks,
wjsjjs: this.formData.wjsjjs instanceof Date ? this.formatDate(this.formData.wjsjjs) : this.formData.wjsjjs
}
const api = this.formData.id ? updateDjzt : addDjzt
const res = await api(submitData)
if (res.code === 200) {
this.$message.success(this.formData.id ? '更新成功' : '新增成功')
this.dialogVisible = false
this.getTableData()
} else {
this.$message.error(res.msg || '操作失败')
}
} catch (error) {
console.error('操作失败:', error)
if (error !== false) {
this.$message.error('操作失败')
} }
} finally {
this.submitLoading = false
}
},
// 分页大小改变
handleSizeChange(val) {
this.pagination.pageSize = val
this.getTableData()
},
// 当前页改变
handleCurrentChange(val) {
this.pagination.currentPage = val
this.getTableData()
},
// 表单重置
resetForm(refName) {
if (this.$refs[refName]) {
this.$refs[refName].resetFields();
}
},
formatTooltip(val) {
return val;
} }
}
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.djzt-container { .djzt-container {
padding: 10px; padding: 10px;
height: calc(100vh - 85px); height: calc(100vh - 85px);
overflow: hidden; overflow: hidden;
position: relative; position: relative;
.search-form { .search-form {
margin-bottom: 10px; margin-bottom: 10px;
} }
.el-table { .el-table {
margin-top: 10px; margin-top: 10px;
} }
} }
::v-deep .el-table--medium .el-table__cell { ::v-deep .el-table--medium .el-table__cell {
padding: 5px 0 !important; padding: 5px 0 !important;
} }
::v-deep.pagination-container { ::v-deep.pagination-container {
padding: 0px !important; padding: 0px !important;
margin: 0; margin: 0;
} }
</style> </style>
\ No newline at end of file
<template> <template>
<div class="drilling-chart-container"> <div class="drilling-chart-container">
<div v-if="jh" class="well-number-display"> <div v-if="jh" class="well-number-display">
<span class="well-label">井号:</span> <span class="well-label">井号:</span>
<span class="well-number">{{ jh }}</span> <span class="well-number">{{ jh }}</span>
</div>
<div class="chart-wrapper"> <span class="well-label" style="margin-left: 10px">开次:</span>
<el-button type="primary" icon="el-icon-download" size="small" class="export-btn" @click="exportChart" <el-select v-model="kc" style="width: 100px" size="mini" clearable placeholder="请选择">
:disabled="!myChart"> <el-option
导出图片 v-for="item in kcData"
</el-button> :key="item.value"
<div id="drillingEfficiencyChart" class="chart"></div> :label="item.label"
</div> :value="item.value">
</el-option>
</el-select>
<span class="well-label" style="margin-left: 10px">钻头尺寸:</span>
<el-input v-model="ztccs" style="width: 100px" clearable size="mini"></el-input>
<el-button type="primary" size="mini" @click="getList">查询</el-button>
<el-button type="primary" icon="el-icon-download" size="mini" @click="exportChart"
:disabled="!myChart"></el-button>
</div> </div>
<div class="chart-wrapper">
<div id="drillingEfficiencyChart" class="chart"></div>
</div>
</div>
</template> </template>
<script> <script>
import * as echarts from 'echarts'; import * as echarts from 'echarts';
import { getqxt } from '@/api/optimization/initialization'; import {getqxt} from '@/api/optimization/initialization';
export default { export default {
props: { props: {
jh: { jh: {
type: String, type: String,
required: true, required: true,
} }
}, },
data() { data() {
return { return {
chartData: null, chartData: null,
myChart: null, myChart: null,
resizeHandler: null resizeHandler: null,
}; kc:'',
}, ztccs:'',
mounted() { kcData:[
this.getList(); {
this.$once('hook:beforeDestroy', this.cleanup); label:'1',
}, value:'1',
methods: { },{
getList() { label:'2',
const params = { jhe: this.jh }; value:'2',
getqxt(params) },{
.then(res => { label:'3',
console.log('接口返回数据:', res); value:'3',
this.chartData = res; },{
this.initChart(); label:'4',
}) value:'4',
.catch(error => { },{
console.error('接口请求失败:', error); label:'5',
this.chartData = null; value:'5',
this.initChart();
});
}, },
]
};
},
mounted() {
this.getList();
this.$once('hook:beforeDestroy', this.cleanup);
},
methods: {
getList() {
const params = {jhe: this.jh,kc:this.kc,ztccs:this.ztccs};
getqxt(params)
.then(res => {
console.log('接口返回数据:', res);
this.chartData = res;
this.initChart();
})
.catch(error => {
console.error('接口请求失败:', error);
this.chartData = null;
this.initChart();
});
},
initChart() {
if (!this.chartData) { initChart() {
const chartDom = document.getElementById('drillingEfficiencyChart'); if (!this.chartData) {
if (chartDom && this.myChart) { const chartDom = document.getElementById('drillingEfficiencyChart');
this.myChart.clear(); if (chartDom && this.myChart) {
} this.myChart.clear();
return; }
} return;
const chartDom = document.getElementById('drillingEfficiencyChart'); }
if (!chartDom) { const chartDom = document.getElementById('drillingEfficiencyChart');
console.error('未找到图表容器'); if (!chartDom) {
return; console.error('未找到图表容器');
} return;
if (chartDom.offsetWidth === 0 || chartDom.offsetHeight === 0) { }
console.log('容器尺寸为0,200ms后重试'); if (chartDom.offsetWidth === 0 || chartDom.offsetHeight === 0) {
setTimeout(() => this.initChart(), 200); console.log('容器尺寸为0,200ms后重试');
return; setTimeout(() => this.initChart(), 200);
} return;
if (this.myChart) { }
this.myChart.dispose(); if (this.myChart) {
} this.myChart.dispose();
this.myChart = echarts.init(chartDom); }
// 解析接口数据(确保折线数据格式正确) this.myChart = echarts.init(chartDom);
const { axisRange, scatterData, targetLineData, crosshair } = this.chartData; // 解析接口数据(确保折线数据格式正确)
// 数据顺序:[speed, depth, drillType, jh, cc] const {axisRange, scatterData, targetLineData, crosshair} = this.chartData;
const scatter = scatterData.map(item => [item.speed, item.depth, item.drillType, item.jh, item.cc]); // 数据顺序:[speed, depth, drillType, jh, cc]
// 折线数据必须为数组格式:[[钻速, 进尺], ...] const scatter = scatterData.map(item => [item.speed, item.depth, item.drillType, item.jh, item.cc]);
const targetLine = targetLineData.map(item => [item.speed, item.depth]); // 折线数据必须为数组格式:[[钻速, 进尺], ...]
const drillTypes = [...new Set(scatterData.map(item => item.drillType))]; const targetLine = targetLineData.map(item => [item.speed, item.depth]);
const colorPalette = ['#3b82f6', '#10b981', '#f59e0b', '#ef4444', '#8b5cf6', '#14b8a6', '#ec4899', '#6366f1', '#f97316', '#0ea5e9']; const drillTypes = [...new Set(scatterData.map(item => item.drillType))];
const typeColorMap = drillTypes.reduce((acc, type, index) => { const colorPalette = ['#3b82f6', '#10b981', '#f59e0b', '#ef4444', '#8b5cf6', '#14b8a6', '#ec4899', '#6366f1', '#f97316', '#0ea5e9'];
acc[type] = colorPalette[index % colorPalette.length]; const typeColorMap = drillTypes.reduce((acc, type, index) => {
return acc; acc[type] = colorPalette[index % colorPalette.length];
}, {}); return acc;
}, {});
// 十字线及中心点配置
const crosshairLines = []; // 十字线及中心点配置
const crosshairCenter = []; const crosshairLines = [];
if (crosshair) { const crosshairCenter = [];
crosshairLines.push({ if (crosshair) {
name: '十字线', crosshairLines.push({
type: 'line', name: '十字线',
data: [[crosshair.y - 10, crosshair.x], [crosshair.y + 10, crosshair.x]], type: 'line',
lineStyle: { color: 'black', width: 1, type: 'dashed' }, data: [[crosshair.y - 10, crosshair.x], [crosshair.y + 10, crosshair.x]],
symbol: 'none', lineStyle: {color: 'black', width: 1, type: 'dashed'},
tooltip: { show: false } // 十字线不显示tooltip symbol: 'none',
}); tooltip: {show: false} // 十字线不显示tooltip
crosshairLines.push({ });
name: '十字线', crosshairLines.push({
type: 'line', name: '十字线',
data: [[crosshair.y, crosshair.x - 500], [crosshair.y, crosshair.x + 500]], type: 'line',
lineStyle: { color: 'black', width: 1, type: 'dashed' }, data: [[crosshair.y, crosshair.x - 500], [crosshair.y, crosshair.x + 500]],
symbol: 'none', lineStyle: {color: 'black', width: 1, type: 'dashed'},
tooltip: { show: false } // 十字线不显示tooltip symbol: 'none',
}); tooltip: {show: false} // 十字线不显示tooltip
crosshairCenter.push({ });
name: '十字线中心', crosshairCenter.push({
type: 'scatter', name: '十字线中心',
data: [[crosshair.y, crosshair.x]], type: 'scatter',
symbolSize: 12, data: [[crosshair.y, crosshair.x]],
itemStyle: { color: 'orange', borderColor: '#fff', borderWidth: 2 } symbolSize: 12,
}); itemStyle: {color: 'orange', borderColor: '#fff', borderWidth: 2}
});
}
// 图表配置项(核心:坐标轴触发,确保折线悬浮显示)
const option = {
title: {text: '钻头钻进能效分析', left: 'center'},
tooltip: {
trigger: 'axis', // 基于坐标轴触发(不依赖数据点)
axisPointer: {
type: 'line', // 显示轴线指示器,辅助定位折线数据点
snap: true // 强制吸附到最近的折线数据点
},
formatter: (params) => {
// 遍历所有系列数据,找到折线图的信息
const lineData = params.find(p => p.seriesName === '优化曲线');
const scatterData = params.find(p => drillTypes.includes(p.seriesName));
const centerData = params.find(p => p.seriesName === '十字线中心');
let result = '';
// // 折线图数据(必显)
// if (lineData) {
// result += `<br>钻速:${lineData.data[0]} m/h<br>进尺:${lineData.data[1]}<br>`;
// }
// 散点数据(如果鼠标在散点上)
if (scatterData) {
const [speed, depth, drillType, jh, cc] = scatterData.data;
result += `井号:${jh}<br>机械钻速m/h${speed} m/h<br>进尺m${depth}<br>钻头型号:${drillType}<br>钻头尺寸mm${cc}`;
} }
// 图表配置项(核心:坐标轴触发,确保折线悬浮显示) // // 中心点数据(如果鼠标在中心点上)
const option = { // if (centerData) {
title: { text: '钻头钻进能效分析', left: 'center' }, // result += `均值<br>钻速:${centerData.data[0]} m/h<br>进尺:${centerData.data[1]}<br>`;
tooltip: { // }
trigger: 'axis', // 基于坐标轴触发(不依赖数据点) return result;
axisPointer: { }
type: 'line', // 显示轴线指示器,辅助定位折线数据点 },
snap: true // 强制吸附到最近的折线数据点 legend: {
}, data: ['指标', '钻速均值', '进尺均值', '优化曲线',],
formatter: (params) => { top: '10%',
// 遍历所有系列数据,找到折线图的信息 right: '5%'
const lineData = params.find(p => p.seriesName === '优化曲线'); },
const scatterData = params.find(p => drillTypes.includes(p.seriesName)); grid: {
const centerData = params.find(p => p.seriesName === '十字线中心'); left: '2%',
let result = ''; right: '5%',
// // 折线图数据(必显) top: '15%',
// if (lineData) { bottom: '10%',
// result += `<br>钻速:${lineData.data[0]} m/h<br>进尺:${lineData.data[1]}<br>`; containLabel: true
// } },
// 散点数据(如果鼠标在散点上) xAxis: {
if (scatterData) { name: '钻速 (m/h)',
const [speed, depth, drillType, jh, cc] = scatterData.data; type: 'value',
result += `井号:${jh}<br>机械钻速m/h${speed} m/h<br>进尺m${depth}<br>钻头型号:${drillType}<br>钻头尺寸mm${cc}`; min: axisRange.xAxis.min,
} max: axisRange.xAxis.max,
// // 中心点数据(如果鼠标在中心点上) interval: axisRange.xAxis.interval,
// if (centerData) { axisLabel: {formatter: '{value} m/h'},
// result += `均值<br>钻速:${centerData.data[0]} m/h<br>进尺:${centerData.data[1]}<br>`; nameLocation: 'center',
// } nameGap: 30,
return result; axisTick: {show: true},
} axisLine: {show: true}
}, },
legend: { yAxis: {
data: ['指标', '钻速均值', '进尺均值', '优化曲线',], name: '进尺',
top: '10%', type: 'value',
right: '5%' min: axisRange.yAxis.min,
}, interval: axisRange.yAxis.interval,
grid: { nameLocation: 'center',
left: '2%', nameGap: 40,
right: '5%', axisTick: {show: true},
top: '15%', axisLine: {show: true}
bottom: '10%', },
containLabel: true series: [
}, {
xAxis: { name: '优化曲线',
name: '钻速 (m/h)', type: 'line',
type: 'value', data: targetLine, // 确保数据正确
min: axisRange.xAxis.min, smooth: true,
max: axisRange.xAxis.max, // 彻底隐藏所有点(包括悬浮时)
interval: axisRange.xAxis.interval, symbol: 'none',
axisLabel: { formatter: '{value} m/h' }, showSymbol: false,
nameLocation: 'center', emphasis: {showSymbol: false},
nameGap: 30, lineStyle: {color: 'red', width: 2}
axisTick: { show: true }, },
axisLine: { show: true } {
}, name: '钻速均值',
yAxis: { type: 'line',
name: '进尺', data: [[crosshair.x, axisRange.yAxis.min], [crosshair.x, axisRange.yAxis.max]],
type: 'value', lineStyle: {color: '#9eca7f', width: 2, type: 'dashed'},
min: axisRange.yAxis.min, symbol: 'none',
interval: axisRange.yAxis.interval, tooltip: {show: false}
nameLocation: 'center', },
nameGap: 40, {
axisTick: { show: true }, name: '进尺均值',
axisLine: { show: true } type: 'line',
}, data: [[crosshair.x - 500, crosshair.y], [crosshair.x + 500, crosshair.y]],
series: [ lineStyle: {color: '#f2ca6b', width: 2},
{ symbol: 'none',
name: '优化曲线', tooltip: {show: false}
type: 'line', },
data: targetLine, // 确保数据正确 ...crosshairLines,
smooth: true, ...crosshairCenter,
// 彻底隐藏所有点(包括悬浮时) ...drillTypes.map(type => {
symbol: 'none', const color = typeColorMap[type];
showSymbol: false, return {
emphasis: { showSymbol: false }, name: type,
lineStyle: { color: 'red', width: 2 } type: 'scatter',
}, data: scatter.filter(item => item[2] === type),
{ symbolSize: 12,
name: '钻速均值', itemStyle: {
type: 'line', color,
data: [[crosshair.x, axisRange.yAxis.min], [crosshair.x, axisRange.yAxis.max]], borderColor: color,
lineStyle: { color: '#9eca7f', width: 2, type: 'dashed' }, borderWidth: 3,
symbol: 'none', shadowColor: color,
tooltip: { show: false } shadowBlur: 8
}, },
{ label: {
name: '进尺均值', show: true,
type: 'line', position: 'top',
data: [[crosshair.x - 500, crosshair.y], [crosshair.x + 500, crosshair.y]], formatter: type,
lineStyle: { color: '#f2ca6b', width: 2 }, fontSize: 10,
symbol: 'none', color
tooltip: { show: false } }
},
...crosshairLines,
...crosshairCenter,
...drillTypes.map(type => {
const color = typeColorMap[type];
return {
name: type,
type: 'scatter',
data: scatter.filter(item => item[2] === type),
symbolSize: 12,
itemStyle: {
color,
borderColor: color,
borderWidth: 3,
shadowColor: color,
shadowBlur: 8
},
label: {
show: true,
position: 'top',
formatter: type,
fontSize: 10,
color
}
};
})
]
}; };
})
]
};
this.myChart.setOption(option); this.myChart.setOption(option);
this.resizeHandler = () => this.myChart.resize(); this.resizeHandler = () => this.myChart.resize();
window.addEventListener('resize', this.resizeHandler); window.addEventListener('resize', this.resizeHandler);
}, },
exportChart() { exportChart() {
if (!this.myChart) { if (!this.myChart) {
this.$message.warning('图表未初始化,无法导出'); this.$message.warning('图表未初始化,无法导出');
return; return;
} }
try { try {
// 获取图表的 base64 图片数据 // 获取图表的 base64 图片数据
const url = this.myChart.getDataURL({ const url = this.myChart.getDataURL({
type: 'png', type: 'png',
pixelRatio: 2, // 提高图片清晰度 pixelRatio: 2, // 提高图片清晰度
backgroundColor: '#fff' backgroundColor: '#fff'
}); });
// 创建下载链接 // 创建下载链接
const link = document.createElement('a'); const link = document.createElement('a');
link.href = url; link.href = url;
link.download = `钻头钻进能效分析_${this.jh}_${new Date().getTime()}.png`; link.download = `钻头钻进能效分析_${this.jh}_${new Date().getTime()}.png`;
document.body.appendChild(link); document.body.appendChild(link);
link.click(); link.click();
document.body.removeChild(link); document.body.removeChild(link);
this.$message.success('图片导出成功'); this.$message.success('图片导出成功');
} catch (error) { } catch (error) {
console.error('导出图片失败:', error); console.error('导出图片失败:', error);
this.$message.error('导出图片失败,请重试'); this.$message.error('导出图片失败,请重试');
} }
}, },
cleanup() { cleanup() {
if (this.myChart) { if (this.myChart) {
this.myChart.dispose(); this.myChart.dispose();
this.myChart = null; this.myChart = null;
} }
if (this.resizeHandler) { if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler); window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null; this.resizeHandler = null;
} }
}
} }
}
}; };
</script> </script>
<style scoped> <style scoped>
.drilling-chart-container { .drilling-chart-container {
width: 100%; width: 100%;
height: 100%; height: 100%;
position: relative; position: relative;
box-sizing: border-box; box-sizing: border-box;
} }
.well-number-display { .well-number-display {
position: absolute; position: absolute;
top: 20px; top: 20px;
left: 10px; left: 10px;
z-index: 10; z-index: 10;
/* background: white; */ /* background: white; */
padding: 4px 8px; padding: 4px 8px;
border-radius: 4px; border-radius: 4px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
} }
.well-number-label { .well-number-label {
color: #606266; color: #606266;
font-weight: normal; font-weight: normal;
font-size: 12px; font-size: 12px;
margin-right: 4px; margin-right: 4px;
} }
.well-number-value { .well-number-value {
color: #409EFF; color: #409EFF;
font-weight: bold; font-weight: bold;
font-size: 13px; font-size: 13px;
text-shadow: 0 0 2px rgba(64, 158, 255, 0.3); text-shadow: 0 0 2px rgba(64, 158, 255, 0.3);
position: relative; position: relative;
} }
.well-number-value::before { .well-number-value::before {
content: ''; content: '';
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
right: 0; right: 0;
bottom: 0; bottom: 0;
background: linear-gradient(135deg, rgba(64, 158, 255, 0.1) 0%, rgba(64, 158, 255, 0.05) 100%); background: linear-gradient(135deg, rgba(64, 158, 255, 0.1) 0%, rgba(64, 158, 255, 0.05) 100%);
border-radius: 2px; border-radius: 2px;
z-index: -1; z-index: -1;
} }
.optimal-values { .optimal-values {
position: absolute; position: absolute;
top: 5px; top: 5px;
left: 5px; left: 5px;
z-index: 10; z-index: 10;
background: linear-gradient(135deg, rgba(255, 255, 255, 0.95) 0%, rgba(248, 250, 252, 0.95) 100%); 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: 1px solid rgba(64, 158, 255, 0.15);
border-radius: 4px; border-radius: 4px;
padding: 4px 8px; 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); 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); backdrop-filter: blur(6px);
min-width: 120px; min-width: 120px;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
} }
.optimal-values:hover { .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); 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); transform: translateY(-2px);
border-color: rgba(64, 158, 255, 0.25); border-color: rgba(64, 158, 255, 0.25);
} }
.optimal-item { .optimal-item {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
margin-bottom: 2px; margin-bottom: 2px;
font-size: 10px; font-size: 10px;
padding: 1px 4px; padding: 1px 4px;
border-radius: 3px; border-radius: 3px;
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
position: relative; position: relative;
} }
.optimal-item:last-child { .optimal-item:last-child {
margin-bottom: 0; margin-bottom: 0;
} }
.optimal-item:hover { .optimal-item:hover {
background: linear-gradient(135deg, rgba(64, 158, 255, 0.08) 0%, rgba(103, 194, 58, 0.08) 100%); background: linear-gradient(135deg, rgba(64, 158, 255, 0.08) 0%, rgba(103, 194, 58, 0.08) 100%);
transform: translateX(2px); transform: translateX(2px);
box-shadow: 0 2px 8px rgba(64, 158, 255, 0.15); box-shadow: 0 2px 8px rgba(64, 158, 255, 0.15);
} }
.optimal-item::before { .optimal-item::before {
content: ''; content: '';
position: absolute; position: absolute;
left: 0; left: 0;
top: 50%; top: 50%;
transform: translateY(-50%); transform: translateY(-50%);
width: 3px; width: 3px;
height: 0; height: 0;
background: linear-gradient(135deg, #409eff 0%, #67c23a 100%); background: linear-gradient(135deg, #409eff 0%, #67c23a 100%);
border-radius: 2px; border-radius: 2px;
transition: height 0.2s ease; transition: height 0.2s ease;
} }
.optimal-item:hover::before { .optimal-item:hover::before {
height: 60%; height: 60%;
} }
.optimal-item .label { .optimal-item .label {
color: #5a5e66; color: #5a5e66;
font-weight: 500; font-weight: 500;
margin-right: 6px; margin-right: 6px;
font-size: 10px; font-size: 10px;
letter-spacing: 0.1px; letter-spacing: 0.1px;
opacity: 0.9; opacity: 0.9;
} }
.optimal-item .value { .optimal-item .value {
color: #2c3e50; color: #2c3e50;
font-weight: 700; font-weight: 700;
font-size: 10px; font-size: 10px;
background: linear-gradient(135deg, #409eff 0%, #67c23a 100%); background: linear-gradient(135deg, #409eff 0%, #67c23a 100%);
-webkit-background-clip: text; -webkit-background-clip: text;
-webkit-text-fill-color: transparent; -webkit-text-fill-color: transparent;
background-clip: text; background-clip: text;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
position: relative; position: relative;
} }
.optimal-item .value::after { .optimal-item .value::after {
content: ''; content: '';
position: absolute; position: absolute;
bottom: -1px; bottom: -1px;
left: 0; left: 0;
width: 100%; width: 100%;
height: 1px; height: 1px;
background: linear-gradient(135deg, #409eff 0%, #67c23a 100%); background: linear-gradient(135deg, #409eff 0%, #67c23a 100%);
opacity: 0; opacity: 0;
transition: opacity 0.2s ease; transition: opacity 0.2s ease;
} }
.optimal-item:hover .value::after { .optimal-item:hover .value::after {
opacity: 0.3; opacity: 0.3;
} }
.chart-wrapper { .chart-wrapper {
position: relative; position: relative;
width: 100%; width: 100%;
height: calc(100vh - 230px); height: calc(100vh - 230px);
min-height: 600px; min-height: 600px;
} }
.chart { .chart {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.export-btn { .export-btn {
position: absolute; position: absolute;
top: 10px; top: 10px;
right: 10px; right: 10px;
z-index: 100; z-index: 100;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
} }
/* 井号显示样式 */ /* 井号显示样式 */
.well-number-display { .well-number-display {
position: absolute; position: absolute;
top: 16px; top: 16px;
left: 16px; left: 16px;
z-index: 5; z-index: 5;
background: transparent; background: transparent;
padding: 8px 12px; padding: 8px 12px;
display: flex; display: flex;
align-items: center; align-items: center;
gap: 6px; gap: 6px;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
transition: all 0.3s ease; transition: all 0.3s ease;
opacity: 0.9; opacity: 0.9;
} }
.well-number-display:hover { .well-number-display:hover {
opacity: 1; opacity: 1;
} }
.well-label { .well-label {
color: #6b7280; color: #6b7280;
font-size: 13px; font-size: 13px;
font-weight: 500; font-weight: 500;
white-space: nowrap; white-space: nowrap;
} }
.well-number { .well-number {
color: #3b82f6; color: #3b82f6;
font-size: 14px; font-size: 14px;
font-weight: 600; font-weight: 600;
} }
</style> </style>
\ No newline at end of file
...@@ -6,16 +6,6 @@ ...@@ -6,16 +6,6 @@
<el-input v-model="queryParams.jh" placeholder="请输入井号" clearable @keyup.enter.native="handleQuery" <el-input v-model="queryParams.jh" placeholder="请输入井号" clearable @keyup.enter.native="handleQuery"
disabled /> disabled />
</el-form-item> </el-form-item>
<!-- <el-form-item label="井号" prop="jh">
<el-input v-model="queryParams.jh" placeholder="请输入井号" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="井眼编号" prop="jybh">
<el-input v-model="queryParams.jybh" placeholder="请输入井眼编号" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="日期" prop="rq">
<el-date-picker clearable v-model="queryParams.rq" type="date" value-format="yyyy-MM-dd" placeholder="请选择日期">
</el-date-picker>
</el-form-item> -->
<el-form-item label="开始井深m" prop="beginJs"> <el-form-item label="开始井深m" prop="beginJs">
<el-input v-model="queryParams.beginJs" placeholder="请输入开始井深" clearable <el-input v-model="queryParams.beginJs" placeholder="请输入开始井深" clearable
@keyup.enter.native="handleQuery" /> @keyup.enter.native="handleQuery" />
...@@ -24,233 +14,24 @@ ...@@ -24,233 +14,24 @@
<el-input v-model="queryParams.endJs" placeholder="请输入结束井深" clearable <el-input v-model="queryParams.endJs" placeholder="请输入结束井深" clearable
@keyup.enter.native="handleQuery" /> @keyup.enter.native="handleQuery" />
</el-form-item> </el-form-item>
<!-- <el-form-item label="垂深" prop="cs">
<el-input v-model="queryParams.cs" placeholder="请输入垂深" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="迟到井深" prop="cdjs">
<el-input v-model="queryParams.cdjs" placeholder="请输入迟到井深" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="钻头型号" prop="ztxh">
<el-input v-model="queryParams.ztxh" placeholder="请输入钻头型号" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="钻头直径" prop="ztzj">
<el-input v-model="queryParams.ztzj" placeholder="请输入钻头直径" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="进尺" prop="jc">
<el-input v-model="queryParams.jc" placeholder="请输入进尺" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="大钩负荷" prop="dgfh">
<el-input v-model="queryParams.dgfh" placeholder="请输入大钩负荷" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="钻压" prop="zy">
<el-input v-model="queryParams.zy" placeholder="请输入钻压" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="转速" prop="zs1">
<el-input v-model="queryParams.zs1" placeholder="请输入转速" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="扭矩" prop="nj">
<el-input v-model="queryParams.nj" placeholder="请输入扭矩" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="顶驱扭矩" prop="dqnj">
<el-input v-model="queryParams.dqnj" placeholder="请输入顶驱扭矩" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="成本" prop="cb">
<el-input v-model="queryParams.cb" placeholder="请输入成本" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="纯钻进时间" prop="zzsj">
<el-input v-model="queryParams.zzsj" placeholder="请输入纯钻进时间" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="运行时间" prop="yxsj">
<el-input v-model="queryParams.yxsj" placeholder="请输入运行时间" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="钻井天数" prop="zjts">
<el-input v-model="queryParams.zjts" placeholder="请输入钻井天数" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="池体积1" prop="ctj1">
<el-input v-model="queryParams.ctj1" placeholder="请输入池体积1" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="池体积2" prop="ctj2">
<el-input v-model="queryParams.ctj2" placeholder="请输入池体积2" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="池体积3" prop="ctj3">
<el-input v-model="queryParams.ctj3" placeholder="请输入池体积3" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="池体积4" prop="ctj4">
<el-input v-model="queryParams.ctj4" placeholder="请输入池体积4" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="池体积5" prop="ctj5">
<el-input v-model="queryParams.ctj5" placeholder="请输入池体积5" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="池体积6" prop="ctj6">
<el-input v-model="queryParams.ctj6" placeholder="请输入池体积6" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="池体积7" prop="ctj7">
<el-input v-model="queryParams.ctj7" placeholder="请输入池体积7" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="池体积8" prop="ctj8">
<el-input v-model="queryParams.ctj8" placeholder="请输入池体积8" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="DC指数" prop="dczs">
<el-input v-model="queryParams.dczs" placeholder="请输入DC指数" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="地层压力梯度" prop="dcyltd">
<el-input v-model="queryParams.dcyltd" placeholder="请输入地层压力梯度" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="破裂压力梯度" prop="plyltd">
<el-input v-model="queryParams.plyltd" placeholder="请输入破裂压力梯度" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="设计地层压力" prop="sjdcyl">
<el-input v-model="queryParams.sjdcyl" placeholder="请输入设计地层压力" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="1号泵冲" prop="yhbc">
<el-input v-model="queryParams.yhbc" placeholder="请输入1号泵冲" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="2号泵冲" prop="ehbc">
<el-input v-model="queryParams.ehbc" placeholder="请输入2号泵冲" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="3号泵冲" prop="shbc">
<el-input v-model="queryParams.shbc" placeholder="请输入3号泵冲" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="总泵冲" prop="zbc">
<el-input v-model="queryParams.zbc" placeholder="请输入总泵冲" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="入口流量" prop="rkll">
<el-input v-model="queryParams.rkll" placeholder="请输入入口流量" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="出口温度" prop="ckll">
<el-input v-model="queryParams.ckll" placeholder="请输入出口温度" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="入口密度" prop="rkmd">
<el-input v-model="queryParams.rkmd" placeholder="请输入入口密度" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="出口密度" prop="ckmd">
<el-input v-model="queryParams.ckmd" placeholder="请输入出口密度" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="入口电导" prop="rkdd">
<el-input v-model="queryParams.rkdd" placeholder="请输入入口电导" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="入口温度" prop="rkwd">
<el-input v-model="queryParams.rkwd" placeholder="请输入入口温度" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="出口温度" prop="ckwd">
<el-input v-model="queryParams.ckwd" placeholder="请输入出口温度" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="总池体积" prop="zctj">
<el-input v-model="queryParams.zctj" placeholder="请输入总池体积" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="泥浆溢漏" prop="njyl">
<el-input v-model="queryParams.njyl" placeholder="请输入泥浆溢漏" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="钻时" prop="zs">
<el-input v-model="queryParams.zs" placeholder="请输入钻时" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="立压" prop="ly">
<el-input v-model="queryParams.ly" placeholder="请输入立压" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="套压" prop="ty">
<el-input v-model="queryParams.ty" placeholder="请输入套压" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="返出时间" prop="fcsj">
<el-input v-model="queryParams.fcsj" placeholder="请输入返出时间" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="DC趋势线" prop="dcqsx">
<el-input v-model="queryParams.dcqsx" placeholder="请输入DC趋势线" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="当量密度" prop="dlmd">
<el-input v-model="queryParams.dlmd" placeholder="请输入当量密度" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="大钩高度" prop="dggd">
<el-input v-model="queryParams.dggd" placeholder="请输入大钩高度" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="瞬时钻时" prop="sszs">
<el-input v-model="queryParams.sszs" placeholder="请输入瞬时钻时" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="顶驱转速" prop="dqzs">
<el-input v-model="queryParams.dqzs" placeholder="请输入顶驱转速" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="DCS孔隙度" prop="dcskxd">
<el-input v-model="queryParams.dcskxd" placeholder="请输入DCS孔隙度" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="SIGMA" prop="sigma">
<el-input v-model="queryParams.sigma" placeholder="请输入SIGMA" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="SIGMA趋向" prop="sigman">
<el-input v-model="queryParams.sigman" placeholder="请输入SIGMA趋向" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="SIGMA地压梯度" prop="sigmadytd">
<el-input v-model="queryParams.sigmadytd" placeholder="请输入SIGMA地压梯度" clearable
@keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="SIGMA破压梯度" prop="sigmapytd">
<el-input v-model="queryParams.sigmapytd" placeholder="请输入SIGMA破压梯度" clearable
@keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="SIGMA孔隙度" prop="sigmakxd">
<el-input v-model="queryParams.sigmakxd" placeholder="请输入SIGMA孔隙度" clearable
@keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="地层提示" prop="dcts">
<el-input v-model="queryParams.dcts" placeholder="请输入地层提示" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="作业类别1" prop="zylb1">
<el-input v-model="queryParams.zylb1" placeholder="请输入作业类别1" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="作业类别2" prop="zylb2">
<el-input v-model="queryParams.zylb2" placeholder="请输入作业类别2" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="录入时间" prop="lrsj">
<el-input v-model="queryParams.lrsj" placeholder="请输入录入时间" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="井眼名称" prop="jymc">
<el-input v-model="queryParams.jymc" placeholder="请输入井眼名称" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="迟到时间" prop="cdsj">
<el-input v-model="queryParams.cdsj" placeholder="请输入迟到时间" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="出口电导" prop="ckdd">
<el-input v-model="queryParams.ckdd" placeholder="请输入出口电导" clearable @keyup.enter.native="handleQuery" />
</el-form-item> -->
<el-form-item> <el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<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" plain icon="el-icon-plus" size="mini" @click="handleAdd" <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
v-hasPermi="['system:ljSssjSd:add']">新增</el-button> >新增</el-button>
<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:ljSssjSd:export']">导出</el-button> >导出</el-button>
<el-button type="success" plain icon="el-icon-upload" size="mini" @click="handleImport" <el-button type="success" plain icon="el-icon-upload" size="mini" @click="handleImport"
v-hasPermi="['system:ljSssjSd:import']">导入</el-button> >导入</el-button>
<el-button type="success" plain size="mini" @click="handleSjtb"
>录井数据同步</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
<!-- <el-row :gutter="10" class="mb8">
<el-col :span="1.5"> <el-table border :data="ljSssjSdList" @selection-change="handleSelectionChange" :height="TableHeight()"
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
v-hasPermi="['system:ljSssjSd:add']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="single" @click="handleUpdate"
v-hasPermi="['system:ljSssjSd:edit']">修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete"
v-hasPermi="['system:ljSssjSd:remove']">删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport"
v-hasPermi="['system:ljSssjSd:export']">导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row> -->
<el-table border :data="ljSssjSdList" @selection-change="handleSelectionChange" height="calc(100vh - 190px)"
style="width: 100%"> style="width: 100%">
<!-- <el-table-column type="selection" width="55" align="center" /> -->
<!-- <el-table-column label="id" align="center" prop="id" /> -->
<!-- <el-table-column label="井号" align="center" prop="jh" min-width="100" show-overflow-tooltip fixed />
<el-table-column label="井眼编号" align="center" prop="jybh" min-width="80" show-overflow-tooltip />
<el-table-column label="日期" align="center" prop="rq" min-width="100" show-overflow-tooltip>
<template slot-scope="scope">
<span>{{ parseTime(scope.row.rq, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column> -->
<el-table-column label="井深" align="center" prop="js" min-width="80" show-overflow-tooltip /> <el-table-column label="井深" align="center" prop="js" min-width="80" show-overflow-tooltip />
<el-table-column label="垂深" align="center" prop="cs" min-width="80" show-overflow-tooltip /> <el-table-column label="垂深" align="center" prop="cs" min-width="80" show-overflow-tooltip />
<!-- <el-table-column label="迟到井深" align="center" prop="cdjs" min-width="90" show-overflow-tooltip /> <!-- <el-table-column label="迟到井深" align="center" prop="cdjs" min-width="90" show-overflow-tooltip />
...@@ -317,9 +98,9 @@ ...@@ -317,9 +98,9 @@
fixed="right"> fixed="right">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
v-hasPermi="['system:ljSssjSd:edit']">修改</el-button> >修改</el-button>
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
v-hasPermi="['system:ljSssjSd:remove']">删除</el-button> >删除</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
...@@ -897,7 +678,7 @@ ...@@ -897,7 +678,7 @@
</template> </template>
<script> <script>
import { listLjSssjSd, getLjSssjSd, delLjSssjSd, addLjSssjSd, updateLjSssjSd } from "@/api/optimization/ljSssjSd"; import { listLjSssjSd, getLjSssjSd, delLjSssjSd, addLjSssjSd, updateLjSssjSd,getLjzmsj } from "@/api/optimization/ljSssjSd";
import { getToken } from "@/utils/auth"; import { getToken } from "@/utils/auth";
export default { export default {
...@@ -1278,6 +1059,20 @@ export default { ...@@ -1278,6 +1059,20 @@ export default {
handleDownloadTemplate() { handleDownloadTemplate() {
this.download('system/ljSssjSd/exportMb', {}, '录井整米数据导入模板.xlsx'); this.download('system/ljSssjSd/exportMb', {}, '录井整米数据导入模板.xlsx');
}, },
handleSjtb(){
this.queryParams.jh
getLjzmsj({jh:this.queryParams.jh}).then(res=>{
console.log(res)
})
},
TableHeight() {
const windowHeight = window.innerHeight;
const topBarHeight = 130;
const componentMargin = 160;
const tableHeight = windowHeight - topBarHeight - componentMargin;
return tableHeight;
},
} }
}; };
</script> </script>
......
...@@ -3,12 +3,21 @@ ...@@ -3,12 +3,21 @@
<div v-if="jh" class="well-number-display"> <div v-if="jh" class="well-number-display">
<span class="well-label">井号:</span> <span class="well-label">井号:</span>
<span class="well-number">{{ jh }}</span> <span class="well-number">{{ jh }}</span>
<span class="well-label" style="margin-left: 10px">钻时颜色</span>
<el-color-picker
v-model="color1"
size="mini"
@change="handleColor"
></el-color-picker>
<el-button
type="primary"
icon="el-icon-download"
size="mini"
@click="exportChart"
:disabled="!myChart"
></el-button>
</div> </div>
<div class="chart-wrapper"> <div class="chart-wrapper">
<!-- <el-button type="primary" icon="el-icon-download" size="small" class="export-btn" @click="exportChart"
:disabled="!myChart">
导出图片
</el-button> -->
<div id="drillingTimeChart" class="chart"></div> <div id="drillingTimeChart" class="chart"></div>
</div> </div>
</div> </div>
...@@ -33,6 +42,8 @@ export default { ...@@ -33,6 +42,8 @@ export default {
myChart: null, myChart: null,
resizeHandler: null, resizeHandler: null,
loading: false, loading: false,
color1: "#FF0000",
option: null,
}; };
}, },
mounted() { mounted() {
...@@ -54,7 +65,7 @@ export default { ...@@ -54,7 +65,7 @@ export default {
} }
this.loading = true; this.loading = true;
// 获取录井曲线数据和录井整米数据 // 获取录井曲线数据和录井整米数据
Promise.all([getljqxData({ jh: this.jh }), listLjSssjSd({ jh: this.jh })]) Promise.all([getljqxData({ jh: this.jh }), listLjSssjSd({ jh: this.jh,pageNum: 1,pageSize:999999 })])
.then(([ljqxRes, ljSssjRes]) => { .then(([ljqxRes, ljSssjRes]) => {
this.chartData = this.processData(ljqxRes, ljSssjRes); this.chartData = this.processData(ljqxRes, ljSssjRes);
this.initChart(); this.initChart();
...@@ -71,6 +82,7 @@ export default { ...@@ -71,6 +82,7 @@ export default {
}, },
processData(ljqxRes, ljSssjRes) { processData(ljqxRes, ljSssjRes) {
console.log("RKLL", ljqxRes);
// 处理录井曲线数据 // 处理录井曲线数据
const processArrayData = (dataList, fieldName) => { const processArrayData = (dataList, fieldName) => {
if (!dataList || !Array.isArray(dataList) || dataList.length === 0) { if (!dataList || !Array.isArray(dataList) || dataList.length === 0) {
...@@ -95,25 +107,12 @@ export default { ...@@ -95,25 +107,12 @@ export default {
: null; : null;
return { depth, value }; return { depth, value };
}) })
.filter(
(item) =>
item.depth !== null &&
item.value !== null &&
item.value !== undefined
);
}; };
// 处理钻时数据(从录井整米数据中获取) // 处理钻时数据(从录井整米数据中获取)
let drillingTimeData = []; let drillingTimeData = [];
if (ljSssjRes && ljSssjRes.rows && Array.isArray(ljSssjRes.rows)) { if (ljSssjRes && ljSssjRes.rows && Array.isArray(ljSssjRes.rows)) {
drillingTimeData = ljSssjRes.rows drillingTimeData = ljSssjRes.rows
.filter(
(item) =>
item.js !== null &&
item.js !== undefined &&
item.zs !== null &&
item.zs !== undefined
)
.map((item) => ({ .map((item) => ({
depth: item.js, depth: item.js,
value: item.zs, value: item.zs,
...@@ -125,24 +124,52 @@ export default { ...@@ -125,24 +124,52 @@ export default {
const standpipePressureData = processArrayData(ljqxRes.lyList, "ly"); const standpipePressureData = processArrayData(ljqxRes.lyList, "ly");
const drillingPressureData = processArrayData(ljqxRes.zyList, "zy"); const drillingPressureData = processArrayData(ljqxRes.zyList, "zy");
const rpmData = processArrayData(ljqxRes.zs1List, "zs1"); const rpmData = processArrayData(ljqxRes.zs1List, "zs1");
const rkllData = processArrayData(ljqxRes.rkllList, "rkll");
// 处理泵冲数据(总泵冲) // 处理泵冲数据(总泵冲)
let pumpStrokeData = []; let pumpStrokeData = [];
if (ljSssjRes && ljSssjRes.rows && Array.isArray(ljSssjRes.rows)) { if (ljSssjRes && ljSssjRes.rows && Array.isArray(ljSssjRes.rows)) {
pumpStrokeData = ljSssjRes.rows pumpStrokeData = ljSssjRes.rows
.filter(
(item) =>
item.js !== null &&
item.js !== undefined &&
item.zbc !== null &&
item.zbc !== undefined
)
.map((item) => ({ .map((item) => ({
depth: item.js, depth: item.js,
value: item.zbc, value: item.zbc,
})); }));
} }
// 处理层位数据,生成层位区间
let formationIntervals = [];
if (ljqxRes.list && Array.isArray(ljqxRes.list)) {
// 按深度排序
const sortedRows = [...ljqxRes.list];
if (sortedRows.length > 0) {
let currentFormation = sortedRows[0].cw;
let currentStartDepth = sortedRows[0].js;
for (let i = 1; i < sortedRows.length; i++) {
const item = sortedRows[i];
if (item.cw !== currentFormation) {
// 记录当前层位区间
formationIntervals.push({
formation: currentFormation,
startDepth: currentStartDepth,
endDepth: sortedRows[i - 1].js,
});
// 开始新的层位区间
currentFormation = item.cw;
currentStartDepth = item.js;
}
}
// 记录最后一个层位区间
formationIntervals.push({
formation: currentFormation,
startDepth: currentStartDepth,
endDepth: sortedRows[sortedRows.length - 1].js,
});
}
}
return { return {
drillingTime: drillingTimeData, drillingTime: drillingTimeData,
torque: torqueData, torque: torqueData,
...@@ -150,6 +177,10 @@ export default { ...@@ -150,6 +177,10 @@ export default {
drillingPressure: drillingPressureData, drillingPressure: drillingPressureData,
rpm: rpmData, rpm: rpmData,
pumpStroke: pumpStrokeData, pumpStroke: pumpStrokeData,
rkllData: rkllData,
formationIntervals: formationIntervals,
minDepth: ljqxRes.scale1,
maxDepth: ljqxRes.scale,
}; };
}, },
...@@ -221,6 +252,8 @@ export default { ...@@ -221,6 +252,8 @@ export default {
drillingPressure, drillingPressure,
rpm, rpm,
pumpStroke, pumpStroke,
rkllData,
formationIntervals,
} = this.chartData; } = this.chartData;
// 转换数据格式为 [depth, value] 格式 // 转换数据格式为 [depth, value] 格式
...@@ -242,12 +275,12 @@ export default { ...@@ -242,12 +275,12 @@ export default {
}; };
const drillingTimeChartData = convertToChartData(drillingTime); const drillingTimeChartData = convertToChartData(drillingTime);
console.log(drillingTimeChartData, "drillingTimeChartData");
const torqueChartData = convertToChartData(torque); const torqueChartData = convertToChartData(torque);
const standpipePressureChartData = convertToChartData(standpipePressure); const standpipePressureChartData = convertToChartData(standpipePressure);
const drillingPressureChartData = convertToChartData(drillingPressure); const drillingPressureChartData = convertToChartData(drillingPressure);
const rpmChartData = convertToChartData(rpm); const rpmChartData = convertToChartData(rpm);
const pumpStrokeChartData = convertToChartData(pumpStroke); const pumpStrokeChartData = convertToChartData(pumpStroke);
const rkllChartData = convertToChartData(rkllData);
// 计算深度范围 // 计算深度范围
const allDepths = [ const allDepths = [
...@@ -257,21 +290,57 @@ export default { ...@@ -257,21 +290,57 @@ export default {
...drillingPressureChartData.map((d) => d[0]), ...drillingPressureChartData.map((d) => d[0]),
...rpmChartData.map((d) => d[0]), ...rpmChartData.map((d) => d[0]),
...pumpStrokeChartData.map((d) => d[0]), ...pumpStrokeChartData.map((d) => d[0]),
...rkllChartData.map((d) => d[0]),
].filter((d) => d !== null && d !== undefined); ].filter((d) => d !== null && d !== undefined);
const minDepth = const minDepth =
allDepths.length > 0 ? Math.floor(Math.min(...allDepths) / 10) * 10 : 0; this.chartData.minDepth - 200 < 0 ? 0 : this.chartData.minDepth - 200;
const maxDepth = const maxDepth = this.chartData.maxDepth + 200;
allDepths.length > 0
? Math.ceil(Math.max(...allDepths) / 10) * 10 // 定义颜色映射表(方便维护和统一管理)
: 1000; const seriesColors = {
"钻时 (min/m)": "#FF0000", // 红色(你之前指定的)
const option = { "扭矩 (kN•m)": "#1E90FF", // 道奇蓝
title: { "立压 (MPa)": "#32CD32", // limegreen
text: "录井钻时图", "钻压 (kN)": "#FFD700", // 金色
left: "center", "转速 (rpm)": "#FF6347", // 番茄红
top: 10, "泵冲": "#9370DB", // 中紫色
"入口流量": "#20B2AA", // 浅钢蓝色
};
// 构建图例数据(带颜色)
const legendData = Object.keys(seriesColors).map((name) => ({
name: name,
itemStyle: {
color: seriesColors[name], // 图例文字颜色与对应折线一致
}, },
}));
// 生成层位背景区域配置
const formationMarkAreas = [];
if (formationIntervals && formationIntervals.length > 0) {
// 定义层位颜色映射表,使用中性颜色
const formationColors = this.generateDistinctColors(formationIntervals.length);
formationIntervals.forEach((interval,index) => {
const color =formationColors[index];
formationMarkAreas.push([
{
xAxis: interval.startDepth,
name: interval.formation,
itemStyle: {
color: color,
opacity: 0.7,
},
},
{
xAxis: interval.endDepth,
},
]);
});
}
this.option = {
tooltip: { tooltip: {
trigger: "axis", trigger: "axis",
axisPointer: { axisPointer: {
...@@ -309,14 +378,7 @@ export default { ...@@ -309,14 +378,7 @@ export default {
}, },
}, },
legend: { legend: {
data: [ data: legendData,
"钻时 (min/m)",
"扭矩 (kN•m)",
"立压 (MPa)",
"钻压 (kN)",
"转速 (rpm)",
"泵冲",
],
top: 40, top: 40,
right: 50, right: 50,
icon: "rect", icon: "rect",
...@@ -381,6 +443,29 @@ export default { ...@@ -381,6 +443,29 @@ export default {
data: drillingTimeChartData, data: drillingTimeChartData,
smooth: true, smooth: true,
symbol: "none", symbol: "none",
lineStyle: {
color: seriesColors["钻时 (min/m)"], // 使用颜色映射表
width: 3,
type: "solid",
},
},
// 新增独立的markArea专用系列(核心修改)
{
name: "formationMarkArea", // 命名不影响legend(可隐藏)
type: "line",
yAxisIndex: 0,
data: [], // 空数据,不绘制任何线条
silent: true, // 完全关闭交互,不响应鼠标事件
lineStyle: {
show: false, // 隐藏数据线
},
markArea: {
silent: true, // 关闭交互
data: formationMarkAreas, // 原markArea数据
},
// 可选:隐藏该系列在legend中的显示(如果不需要)
legendHoverLink: false,
}, },
{ {
name: "扭矩 (kN•m)", name: "扭矩 (kN•m)",
...@@ -388,8 +473,12 @@ export default { ...@@ -388,8 +473,12 @@ export default {
yAxisIndex: 0, yAxisIndex: 0,
data: torqueChartData, data: torqueChartData,
smooth: true, smooth: true,
symbol: "none", symbol: "none",
lineStyle: {
color: seriesColors["扭矩 (kN•m)"], // 指定颜色
width: 1, // 默认宽度,可根据需要调整
},
}, },
{ {
name: "立压 (MPa)", name: "立压 (MPa)",
...@@ -397,8 +486,11 @@ export default { ...@@ -397,8 +486,11 @@ export default {
yAxisIndex: 0, yAxisIndex: 0,
data: standpipePressureChartData, data: standpipePressureChartData,
smooth: true, smooth: true,
symbol: "none", symbol: "none",
lineStyle: {
color: seriesColors["立压 (MPa)"], // 指定颜色
width: 1,
},
}, },
{ {
name: "钻压 (kN)", name: "钻压 (kN)",
...@@ -406,8 +498,11 @@ export default { ...@@ -406,8 +498,11 @@ export default {
yAxisIndex: 1, yAxisIndex: 1,
data: drillingPressureChartData, data: drillingPressureChartData,
smooth: true, smooth: true,
symbol: "none", symbol: "none",
lineStyle: {
color: seriesColors["钻压 (kN)"], // 指定颜色
width: 1,
},
}, },
{ {
name: "转速 (rpm)", name: "转速 (rpm)",
...@@ -415,8 +510,11 @@ export default { ...@@ -415,8 +510,11 @@ export default {
yAxisIndex: 1, yAxisIndex: 1,
data: rpmChartData, data: rpmChartData,
smooth: true, smooth: true,
symbol: "none", symbol: "none",
lineStyle: {
color: seriesColors["转速 (rpm)"], // 指定颜色
width: 1,
},
}, },
{ {
name: "泵冲", name: "泵冲",
...@@ -424,17 +522,105 @@ export default { ...@@ -424,17 +522,105 @@ export default {
yAxisIndex: 1, yAxisIndex: 1,
data: pumpStrokeChartData, data: pumpStrokeChartData,
smooth: true, smooth: true,
symbol: "none", symbol: "none",
lineStyle: {
color: seriesColors["泵冲"], // 指定颜色
width: 1,
},
},
{
name: "入口流量",
type: "line",
yAxisIndex: 1,
data: rkllChartData,
smooth: true,
symbol: "none",
lineStyle: {
color: seriesColors["入口流量"], // 指定颜色
width: 1,
},
}, },
], ],
}; };
this.myChart.setOption(option); this.myChart.setOption(this.option);
this.resizeHandler = () => this.myChart.resize(); this.resizeHandler = () => this.myChart.resize();
window.addEventListener("resize", this.resizeHandler); window.addEventListener("resize", this.resizeHandler);
}, },
/**
* 生成指定数量的高区分度、亮度适中的十六进制颜色
* @param {Number} count - 需要生成的颜色数量
* @returns {Array} 颜色数组,格式如 ['#F5F5F5', '#E18728', ...]
*/
generateDistinctColors(count) {
// 校验参数:确保count是正整数
if (!Number.isInteger(count) || count < 1) {
console.error('颜色数量必须是正整数');
return [];
}
const colors = [];
// 色相步长:均匀分配0-360°的色相,保证区分度
const hueStep = 360 / count;
// 固定饱和度(55%)和亮度(75%),确保颜色不暗、不亮、不浅
const saturation = 55; // 饱和度范围50-70%最佳
const lightness = 75; // 亮度范围60-85%最佳
for (let i = 0; i < count; i++) {
// 计算当前色相(循环分配,避免重复)
const hue = (i * hueStep) % 360;
// 将HSL转换为十六进制颜色
const hexColor = this.hslToHex(hue, saturation, lightness);
colors.push(hexColor);
}
return colors;
},
/**
* HSL转十六进制颜色(核心工具方法)
* @param {Number} h - 色相(0-360)
* @param {Number} s - 饱和度(0-100)
* @param {Number} l - 亮度(0-100)
* @returns {String} 十六进制颜色,如 #F5F5F5
*/
hslToHex(h, s, l) {
// 转换饱和度/亮度为0-1的小数
s = s / 100;
l = l / 100;
// HSL转RGB核心公式
const c = (1 - Math.abs(2 * l - 1)) * s;
const x = c * (1 - Math.abs(((h / 60) % 2) - 1));
const m = l - c / 2;
let r, g, b;
if (h >= 0 && h < 60) {
r = c; g = x; b = 0;
} else if (h >= 60 && h < 120) {
r = x; g = c; b = 0;
} else if (h >= 120 && h < 180) {
r = 0; g = c; b = x;
} else if (h >= 180 && h < 240) {
r = 0; g = x; b = c;
} else if (h >= 240 && h < 300) {
r = x; g = 0; b = c;
} else {
r = c; g = 0; b = x;
}
// 转换为0-255的整数,并加上亮度偏移量m
r = Math.round((r + m) * 255);
g = Math.round((g + m) * 255);
b = Math.round((b + m) * 255);
// 转换为两位十六进制字符串(补零)
const toHex = (num) => num.toString(16).padStart(2, '0');
return `#${toHex(r)}${toHex(g)}${toHex(b)}`.toUpperCase();
},
exportChart() { exportChart() {
if (!this.myChart) { if (!this.myChart) {
this.$message.warning("图表未初始化,无法导出"); this.$message.warning("图表未初始化,无法导出");
...@@ -471,6 +657,36 @@ export default { ...@@ -471,6 +657,36 @@ export default {
this.resizeHandler = null; this.resizeHandler = null;
} }
}, },
handleColor() {
if (!this.myChart || !this.option) {
return;
}
// 统一颜色格式:确保色值带 # 前缀
const targetColor = this.color1.startsWith("#")
? this.color1
: `#${this.color1}`;
// 1. 更新钻时系列的折线颜色
const drillingTimeSeriesIndex = this.option.series.findIndex(
(item) => item.name === "钻时 (min/m)"
);
if (drillingTimeSeriesIndex !== -1) {
this.option.series[drillingTimeSeriesIndex].lineStyle.color =
targetColor;
}
// 2. 更新图例中钻时项的颜色
const drillingTimeLegendIndex = this.option.legend.data.findIndex(
(item) => item.name === "钻时 (min/m)"
);
if (drillingTimeLegendIndex !== -1) {
this.option.legend.data[drillingTimeLegendIndex].itemStyle.color =
targetColor;
}
// 3. 重新设置 ECharts 配置,生效样式
this.myChart.setOption(this.option);
},
}, },
}; };
</script> </script>
......
<template> <template>
<div class="chart-container"> <div class="chart-container">
<div v-if="jh" class="well-number-display"> <div v-if="jh" style="margin: 0px 10px">
<span class="well-label">井号:</span> <span class="well-label">井号:</span>
<span class="well-number">{{ jh }}</span> <span class="well-number">{{ jh }}</span>
</div>
<div class="export-button-container"> <span class="well-label" style="margin-left: 10px">开次:</span>
<el-select v-model="kc" style="width: 100px" size="mini" clearable placeholder="请选择">
<el-option
v-for="item in kcData"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
<span class="well-label" style="margin-left: 10px">钻头尺寸:</span>
<el-input v-model="ztccs" style="width: 100px" clearable size="mini"></el-input>
<el-button type="primary" style="margin-left: 10px" size="mini" @click="getList">查询</el-button>
<el-button <el-button
class="export-btn" type="primary"
@click="exportChart" @click="exportChart"
:disabled="loading || !myChart" :disabled="loading || !myChart"
title="导出图表为图片" title="导出图表为图片"
icon="el-icon-download" icon="el-icon-download"
> size="mini"
导出 > </el-button>
</el-button>
</div> </div>
<div class="chart-layout"> <div class="chart-layout">
<div id="mainzft" class="chart" ref="chartRef"></div> <div id="mainzft" class="chart" ref="chartRef"></div>
<aside v-if="legendItems && legendItems.length" class="strata-legend"> <aside v-if="legendItems && legendItems.length" class="strata-legend">
<div class="legend-header">层位图例</div> <div class="legend-header">层位图例</div>
<div class="legend-list"> <div class="legend-list">
<div <div
v-for="(item, index) in legendItems" v-for="(item, index) in legendItems"
...@@ -70,6 +82,26 @@ export default { ...@@ -70,6 +82,26 @@ export default {
lastStackedAreas: null, lastStackedAreas: null,
lastChartConfig: null, lastChartConfig: null,
lastXAxisLabels: null, lastXAxisLabels: null,
kc:'',
ztccs:'',
kcData:[
{
label:'1',
value:'1',
},{
label:'2',
value:'2',
},{
label:'3',
value:'3',
},{
label:'4',
value:'4',
},{
label:'5',
value:'5',
},
]
}; };
}, },
computed: { computed: {
...@@ -295,7 +327,7 @@ export default { ...@@ -295,7 +327,7 @@ export default {
// 获取数据 // 获取数据
async getList() { async getList() {
try { try {
const res = await getZft({ jhe: this.jh }); const res = await getZft({ jhe: this.jh,kc:this.kc,ztccs:this.ztccs });
this.mockData = res?.mockData || {}; this.mockData = res?.mockData || {};
const legendList = Array.isArray(res?.tlList) const legendList = Array.isArray(res?.tlList)
? res.tlList ? res.tlList
...@@ -702,7 +734,7 @@ export default { ...@@ -702,7 +734,7 @@ export default {
type: "bar", type: "bar",
stack: "total", stack: "total",
silent: true, silent: true,
barWidth: "8%", barWidth: "10%",
itemStyle: { itemStyle: {
borderColor: "transparent", borderColor: "transparent",
color: "transparent", color: "transparent",
...@@ -848,12 +880,12 @@ export default { ...@@ -848,12 +880,12 @@ export default {
const colors = this.colorScheme; const colors = this.colorScheme;
chartDom.innerHTML = ` chartDom.innerHTML = `
<div class="empty-state" style=" <div class="empty-state" style="
width: 100%; width: 100%;
height: 100%; height: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
color: ${colors.text}; color: ${colors.text};
font-size: 16px; font-size: 16px;
background: ${colors.background}; background: ${colors.background};
...@@ -861,18 +893,18 @@ export default { ...@@ -861,18 +893,18 @@ export default {
box-shadow: 0 4px 12px rgba(0,0,0,0.1); box-shadow: 0 4px 12px rgba(0,0,0,0.1);
"> ">
<div style=" <div style="
font-size: 48px; font-size: 48px;
margin-bottom: 16px; margin-bottom: 16px;
opacity: 0.6; opacity: 0.6;
color: ${colors.primary}; color: ${colors.primary};
">📊</div> ">📊</div>
<div style=" <div style="
font-size: 18px; font-size: 18px;
color: ${colors.text}; color: ${colors.text};
font-weight: 500; font-weight: 500;
">暂无数据</div> ">暂无数据</div>
<div style=" <div style="
font-size: 14px; font-size: 14px;
color: ${colors.text}; color: ${colors.text};
opacity: 0.6; opacity: 0.6;
margin-top: 8px; margin-top: 8px;
...@@ -979,7 +1011,7 @@ export default { ...@@ -979,7 +1011,7 @@ export default {
gap: 5px; gap: 5px;
align-items: stretch; align-items: stretch;
justify-content: flex-start; justify-content: flex-start;
overflow: hidden; overflow: auto;
} }
.strata-legend { .strata-legend {
...@@ -1080,7 +1112,7 @@ export default { ...@@ -1080,7 +1112,7 @@ export default {
flex: 1; flex: 1;
width: 100%; width: 100%;
max-width: 100%; max-width: 100%;
height: 100%; height: 110%;
min-height: 400px; min-height: 400px;
display: block; display: block;
border-radius: 16px; border-radius: 16px;
...@@ -1168,7 +1200,7 @@ export default { ...@@ -1168,7 +1200,7 @@ export default {
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);
} */ } */
......
<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="wellDepthStructure">
<WellDepthStructure v-if="activeTab === 'wellDepthStructure'" :jh="queryParams.jh"
:key="`wellDepthStructure-${queryParams.jh}`" />
</el-tab-pane>
<el-tab-pane label="钻头使用数据" name="dataTable">
<DataTable v-if="activeTab === 'dataTable'" :jh="queryParams.jh" :key="`dataTable-${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 v-if="activeTab === 'curveGraph'" :jh="queryParams.jh" <CurveGraph v-if="activeTab === 'curveGraph'" :jh="queryParams.jh"
:key="`curveGraph-${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 v-if="activeTab === 'histogramGraph'" :jh="queryParams.jh" <HistogramGraph v-if="activeTab === 'histogramGraph'" :jh="queryParams.jh"
:key="`histogramGraph-${queryParams.jh}`" /> :key="`histogramGraph-${queryParams.jh}`" />
</el-tab-pane> </el-tab-pane>
...@@ -32,7 +36,7 @@ ...@@ -32,7 +36,7 @@
:jh="queryParams.jh" :key="`drillingCurve-${queryParams.jh}`" /> :jh="queryParams.jh" :key="`drillingCurve-${queryParams.jh}`" />
</keep-alive> </keep-alive>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="录井钻时图" name="drillingTimeChart"> <el-tab-pane label="钻时及功能参数" name="drillingTimeChart">
<DrillingTimeChart v-if="activeTab === 'drillingTimeChart'" :jh="queryParams.jh" <DrillingTimeChart v-if="activeTab === 'drillingTimeChart'" :jh="queryParams.jh"
:key="`drillingTimeChart-${queryParams.jh}`" /> :key="`drillingTimeChart-${queryParams.jh}`" />
</el-tab-pane> </el-tab-pane>
...@@ -40,10 +44,7 @@ ...@@ -40,10 +44,7 @@
<WellboreTrajectory v-if="activeTab === 'wellboreTrajectory'" :jh="queryParams.jh" <WellboreTrajectory v-if="activeTab === 'wellboreTrajectory'" :jh="queryParams.jh"
:key="`wellboreTrajectory-${queryParams.jh}`" /> :key="`wellboreTrajectory-${queryParams.jh}`" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="井身结构" name="wellDepthStructure">
<WellDepthStructure v-if="activeTab === 'wellDepthStructure'" :jh="queryParams.jh"
:key="`wellDepthStructure-${queryParams.jh}`" />
</el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
</template> </template>
...@@ -76,7 +77,7 @@ export default { ...@@ -76,7 +77,7 @@ export default {
data() { data() {
return { return {
// 当前激活的tab // 当前激活的tab
activeTab: 'dataTable', activeTab: 'wellDepthStructure',
// 显示搜索条件 // 显示搜索条件
showSearch: true, showSearch: true,
// 遮罩层 // 遮罩层
...@@ -185,4 +186,4 @@ export default { ...@@ -185,4 +186,4 @@ export default {
padding: 5px 0; padding: 5px 0;
margin-top: -10px; margin-top: -10px;
} }
</style> </style>
\ No newline at end of file
...@@ -778,7 +778,7 @@ export default { ...@@ -778,7 +778,7 @@ export default {
}, },
handleChangeAr() { handleChangeAr() {
if (this.radio == "3") { if (this.formAr.radio == "3") {
var item = this.sfcs; var item = this.sfcs;
console.log(item, "item"); console.log(item, "item");
this.$router.push({ this.$router.push({
...@@ -789,7 +789,7 @@ export default { ...@@ -789,7 +789,7 @@ export default {
qkmc: item.qkmc, qkmc: item.qkmc,
}, },
}); });
} else if (this.radio == "6") { } else if (this.formAr.radio == "6") {
this.$message({ this.$message({
message: "正在开发中!", message: "正在开发中!",
type: "warning", type: "warning",
......
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