|
|
|
|
<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 style="width: 100%; height: 700px; background: #f0f2f5" ref="lineChart"></div>
|
|
|
|
|
</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,
|
|
|
|
|
size: 'medium',
|
|
|
|
|
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: 'bpartName',
|
|
|
|
|
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: 'left',
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
isSubOpen: false,
|
|
|
|
|
isComponentOpen: false,
|
|
|
|
|
data: [],
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
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({ partCode: 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;
|
|
|
|
|
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 = 14) {
|
|
|
|
|
// 中文字符宽度≈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) {
|
|
|
|
|
const mapBoxEchart = this.$echarts.init(this.$refs.lineChart);
|
|
|
|
|
const option = {
|
|
|
|
|
series: [
|
|
|
|
|
{
|
|
|
|
|
roam: true,
|
|
|
|
|
type: 'tree',
|
|
|
|
|
data: value || [],
|
|
|
|
|
top: '20%',
|
|
|
|
|
left: '7%',
|
|
|
|
|
bottom: '20%',
|
|
|
|
|
right: '20%',
|
|
|
|
|
expandAndCollapse: false,
|
|
|
|
|
animationDuration: 550,
|
|
|
|
|
animationDurationUpdate: 750,
|
|
|
|
|
orient: 'vertical',
|
|
|
|
|
symbol: 'roundRect',
|
|
|
|
|
itemStyle: {
|
|
|
|
|
color: '#284c89',
|
|
|
|
|
},
|
|
|
|
|
// 动态计算节点大小:宽度=最长文本宽度,高度=行数*行高+内边距
|
|
|
|
|
symbolSize: params => {
|
|
|
|
|
// 容错:params为空/无name时给默认值
|
|
|
|
|
const nodeName = params?.name || '未知节点';
|
|
|
|
|
const childCount = params?.children?.length || 0;
|
|
|
|
|
const childText = `${childCount}个子件`;
|
|
|
|
|
// 计算文本宽度
|
|
|
|
|
const textWidth = Math.max(nodeName.length * 12, childText.length * 12) + 20;
|
|
|
|
|
return [Math.max(textWidth, 100), 60]; // 高度设为60px(适配两行文本)
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
label: {
|
|
|
|
|
position: 'inside',
|
|
|
|
|
show: true,
|
|
|
|
|
align: 'center',
|
|
|
|
|
verticalAlign: 'middle',
|
|
|
|
|
fontSize: 14,
|
|
|
|
|
color: '#fff',
|
|
|
|
|
formatter: params => {
|
|
|
|
|
const childText =
|
|
|
|
|
params.data.children?.length > 0 ? `${params.data.children.length}个子件` : '';
|
|
|
|
|
// 去掉模板字符串缩进,用\n换行,避免多余空白
|
|
|
|
|
return `${params.name}${childText ? '\n' + childText : ''}`;
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
};
|
|
|
|
|
// 使用制定的配置项和数据显示图表
|
|
|
|
|
mapBoxEchart.setOption(option, true);
|
|
|
|
|
// // 窗口大小改变时,重新渲染图表
|
|
|
|
|
window.addEventListener(
|
|
|
|
|
'resize',
|
|
|
|
|
function () {
|
|
|
|
|
mapBoxEchart.resize();
|
|
|
|
|
},
|
|
|
|
|
200
|
|
|
|
|
);
|
|
|
|
|
// 4. 核心:监听点击事件,实现label跳转
|
|
|
|
|
mapBoxEchart.on('click', params => {
|
|
|
|
|
// 过滤条件:仅点击节点(label/text)时触发,排除连接线等
|
|
|
|
|
if (params.componentType === 'series' && params.seriesType === 'tree' && params.data) {
|
|
|
|
|
window.open(`${params.data.docLink}`, '_blank');
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
</script>
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
.form-box {
|
|
|
|
|
height: 700px;
|
|
|
|
|
}
|
|
|
|
|
</style>
|