中航光电热表web
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

374 lines
12 KiB

<template>
<basic-container>
<!-- <el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="部件-子件" name="1"></el-tab-pane>
<el-tab-pane label="部件-模具" name="2"></el-tab-pane>
<el-tab-pane label="模具-子件" name="3"></el-tab-pane>
</el-tabs> -->
<!-- <pieceChildQuery v-if="activeName=='1'"></pieceChildQuery>
<sinterMoldNew v-if="activeName=='2'"></sinterMoldNew>
<moldChild v-if="activeName=='3'"></moldChild> -->
<el-form :model="form" label-width="60" label-position="left">
<el-row :gutter="24">
<el-col :span="6">
<el-form-item label="部件号:">
<el-input v-model="form.bujian" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="子件号:">
<el-input v-model="form.zijian" />
</el-form-item>
</el-col>
<el-col :span="12">
<div style="float: right">
<el-button type="primary" icon="search" @click="searchFn()">查询</el-button>
<el-button icon="refreshLeft" @click="resetFn()">重置</el-button>
</div>
</el-col>
</el-row>
</el-form>
<div class="form-box">
<div v-if="isComponentOpen">
<div v-if="dataTree.length > 0" class="form-bom" ref="lineChart"></div>
<el-empty v-else description="数据为空"></el-empty>
</div>
<div v-if="isSubOpen">
<avue-crud
:option="option"
:table-loading="loading"
:data="data"
v-model="form"
v-model:page="page"
ref="crud"
@row-del="rowDel"
@search-change="searchChange"
@search-reset="searchReset"
@selection-change="selectionChange"
@current-change="currentChange"
@size-change="sizeChange"
@refresh-change="refreshChange"
@on-load="onLoad"
>
<template #bpartCode="scope">
<el-button type="text" @click="linkToPartTree(scope.row)">{{
scope.row.bpartCode
}}</el-button>
</template>
</avue-crud>
</div>
</div>
</basic-container>
</template>
<script>
// import pieceChildQuery from './components/pieceChildQuery.vue'
// import sinterMoldNew from './components/sinterMoldNew.vue'
// import moldChild from './components/moldChild.vue'
import { getSinteringPart, getDsPartTree } from '@/api/processManagement/sinTerBOM';
export default {
components: {
// pieceChildQuery,
// sinterMoldNew,
// moldChild
},
data() {
return {
activeName: '1',
form: {
bujian: '',
zijian: '',
},
option: {
height: 'auto',
calcHeight: 32,
tip: false,
simplePage: true,
searchShow: true,
searchMenuSpan: 6,
searchIcon: true,
searchIndex: 3,
tree: false,
border: true,
index: true,
selection: false,
viewBtn: false,
delBtn: false,
addBtn: false,
editBtn: false,
editBtnText: '修改',
addBtnIcon: ' ',
viewBtnIcon: ' ',
delBtnIcon: ' ',
editBtnIcon: ' ',
viewBtnText: '详情',
labelWidth: 120,
menuWidth: 100,
dialogWidth: 640,
dialogClickModal: false,
searchEnter: true,
excelBtn: false,
filterBtn: true,
searchShowBtn: false,
columnSort: true,
excelBtn: true,
columnSort: true,
showOverflowTooltip: true,
gridBtn: false,
searchLabelPosition: 'left',
searchGutter: 24,
searchSpan: 6,
menuAlign: 'left',
gridBtn: false,
searchMenuPosition: 'right',
addBtnIcon: ' ',
viewBtnIcon: ' ',
delBtnIcon: ' ',
editBtnIcon: ' ',
header: false,
menu: false,
align: 'center',
column: [
{
label: '部件号',
prop: 'bpartCode',
sortable: true,
filter: true,
span: 24,
search: false,
headerAlign: 'center',
align: 'center',
},
{
label: '子件号',
prop: 'zpartCode',
sortable: true,
filter: true,
span: 24,
search: false,
headerAlign: 'center',
align: 'center',
},
{
label: '子件名称',
prop: 'zpartName',
sortable: true,
filter: true,
span: 24,
search: false,
headerAlign: 'center',
align: 'center',
},
],
},
isSubOpen: false,
isComponentOpen: false,
data: [],
dataTree: [],
};
},
methods: {
// 点击子件中的部件号 跳转到部件树
linkToPartTree(row) {
this.isComponentOpen = true;
this.isSubOpen = false;
getDsPartTree({ partCode: row.bpartCode, zPartCode: '' }).then(res => {
let resData = res.data.data;
let arr = JSON.parse(JSON.stringify(resData).replace(/partName/g, 'name'));
this.$nextTick(() => {
this.createBarChart(arr);
});
});
},
searchFn() {
if (this.form.zijian != '') {
this.isComponentOpen = false;
this.isSubOpen = true;
getSinteringPart({ bPartCode: this.form.bujian, zPartCode: this.form.zijian }).then(res => {
this.data = res.data.data;
});
} else if (this.form.bujian != '') {
this.isComponentOpen = true;
this.isSubOpen = false;
getDsPartTree({ partCode: this.form.bujian, zPartCode: this.form.zijian }).then(res => {
let resData = res.data.data;
this.dataTree = res.data.data;
let arr = JSON.parse(JSON.stringify(resData).replace(/partName/g, 'name'));
this.$nextTick(() => {
this.createBarChart(arr);
});
});
}
if (this.form.zijian == '' && this.form.bujian == '') {
this.isSubOpen = false;
this.isComponentOpen = false;
}
},
// 获取子件列表
resetFn() {
this.form.zijian = '';
this.form.bujian = '';
this.isSubOpen = false;
this.isComponentOpen = false;
},
getTextWidth(text, fontSize = 12) {
// 中文字符宽度≈fontSize,英文字符≈fontSize/2,加额外内边距
const cnChar = text.replace(/[a-zA-Z0-9]/g, '').length;
const enChar = text.length - cnChar;
return cnChar * fontSize + enChar * (fontSize / 2) + 20; // +20 内边距
},
// 图表
createBarChart(value) {
// 销毁旧的 ECharts 实例
if (this.mapBoxEchart) {
this.mapBoxEchart.dispose();
this.mapBoxEchart = null;
}
this.$nextTick(() => {
if (!this.$refs.lineChart) return;
const chartWidth = this.calculateChartWidth(value);
this.$refs.lineChart.style.width = chartWidth + 'px';
const mapBoxEchart = this.$echarts.init(this.$refs.lineChart);
this.mapBoxEchart = mapBoxEchart;
const option = {
tooltip: {
trigger: 'item',
triggerOn: 'mousemove',
},
series: [
{
roam: true,
type: 'tree',
data: value || [],
top: '10%',
left: '5%',
bottom: '10%',
right: '10%',
expandAndCollapse: false, // 允许展开收起
initialTreeDepth: 2, // 初始展开层级
animationDuration: 550,
animationDurationUpdate: 750,
orient: 'vertical',
symbol: 'roundRect',
itemStyle: {
color: '#284c89',
borderWidth: 2,
borderColor: '#fff',
borderRadius: 2,
},
// 节点间距配置(关键)
// nodePadding: [30, 100], // [上下间距,左右间距]
// layerPadding: 80, // 层级间距
// 动态计算节点大小
symbolSize: (val, params) => {
const nodeData = params?.data || params;
const nodeName = nodeData?.name || '工序';
const nodePartCode = nodeData?.partCode || '';
const nodeQuota = nodeData.quota ? nodeData.quota : '';
// 计算文本宽度
const nameWidth = this.getTextWidth(nodeName);
const codeWidth = this.getTextWidth(nodePartCode);
const quotaWidth = nodeQuota ? this.getTextWidth(`${nodeQuota}`) : 0;
const maxWidth = Math.max(nameWidth, codeWidth, quotaWidth, 60);
// 动态计算行数
let lineCount = 2;
if (nodeQuota !== '' && nodeQuota !== null) {
lineCount = 3;
}
const height = lineCount * 20 + 15;
return [Math.max(maxWidth, 60), height];
},
label: {
position: 'inside',
show: true,
align: 'center',
verticalAlign: 'middle',
fontSize: 12,
lineHeight: 18,
color: '#fff',
formatter: params => {
const nodeData = params.data || params;
nodeData.quota = nodeData.quota==-1?null:nodeData.quota
const quotaText = nodeData.quota != null ? `${nodeData.quota}` : '';
let result = `${nodeData.partCode}\n${nodeData.name}`;
if (quotaText) {
result += '\n' + quotaText;
}
return result;
},
},
// 连线样式
lineStyle: {
color: '#ccc',
width: 1.5,
curveness: 0.5,
},
},
],
};
mapBoxEchart.setOption(option, true);
window.addEventListener('resize', () => {
if (this.mapBoxEchart) {
this.mapBoxEchart.resize();
}
});
mapBoxEchart.on('dblclick', params => {
if (params.componentType === 'series' && params.seriesType === 'tree' && params.data) {
window.open(`${params.data.docLink}`, '_blank');
}
});
});
},
// 计算图表所需宽度
calculateChartWidth(data) {
if (!data || data.length === 0) return 1000;
let maxChildren = 0;
let maxDepth = 0;
const traverse = (nodes, depth = 0) => {
if (!nodes || nodes.length === 0) return;
maxDepth = Math.max(maxDepth, depth);
nodes.forEach(node => {
if (node.children && node.children.length > 0) {
maxChildren = Math.max(maxChildren, node.children.length);
traverse(node.children, depth + 1);
}
});
};
traverse(data);
// 根据子节点数量和层级计算宽度
// 每个节点约 200px,每层约 150px
const width = Math.max(
maxChildren * 200,
maxDepth * 150,
1000 // 最小宽度 1000px
);
console.log('图表宽度计算:', { maxChildren, maxDepth, width });
return width;
},
},
};
</script>
<style lang="scss" scoped>
.form-bom {
height: calc(100vh - 60px - 40px - 10px - 90px - 31px);
min-width: 100%;
background: #f0f2f5;
overflow: visible; // 让 ECharts 自由扩展
}
</style>