中航光电热表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.

317 lines
9.9 KiB

<template>
5 months ago
<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>
6 months ago
</el-tabs> -->
5 months ago
<!-- <pieceChildQuery v-if="activeName=='1'"></pieceChildQuery>
<sinterMoldNew v-if="activeName=='2'"></sinterMoldNew>
6 months ago
<moldChild v-if="activeName=='3'"></moldChild> -->
5 months ago
<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>
6 months ago
5 months ago
<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>
5 months ago
</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>
5 months ago
</div>
</div>
</basic-container>
</template>
<script>
5 months ago
// 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 {
5 months ago
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',
5 months ago
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',
5 months ago
},
],
},
isSubOpen: false,
isComponentOpen: false,
data: [],
dataTree: [],
5 months ago
};
},
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);
});
});
},
5 months ago
searchFn() {
if (this.form.zijian != '') {
this.isComponentOpen = false;
this.isSubOpen = true;
getSinteringPart({ bPartCode: this.form.bujian, zPartCode: this.form.zijian }).then(res => {
5 months ago
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 => {
5 months ago
let resData = res.data.data;
this.dataTree = res.data.data;
5 months ago
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;
}
6 months ago
},
5 months ago
// 获取子件列表
6 months ago
5 months ago
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',
4 weeks ago
borderWidth: 2,
borderColor: '#fff',
borderRadius: 4, // 圆角半径,值越大圆角越明显
paddingLeft: 10,
5 months ago
},
// 动态计算节点大小:宽度=最长文本宽度,高度=行数*行高+内边距
4 weeks ago
symbolSize: (val, params) => {
5 months ago
// 容错:params为空/无name时给默认值
const nodeName = params?.name || '未知节点';
const childCount = params?.children?.length || 0;
const childText = `${childCount}个子件`;
const nodeQuota = nodeData?.quota !== undefined ? nodeData.quota : '';
5 months ago
// 计算文本宽度
4 weeks ago
const textWidth = Math.max(nodeName.length * 12, childText.length * 12) + 30;
// 动态计算行数
let lineCount = 2; // 默认 2 行(partCode + name)
if (nodeQuota !== '' && nodeQuota !== null) {
lineCount = 3; // 有 quota 时 3 行
}
// 计算高度:每行 20px + 上下内边距 20px
const height = lineCount * 20 + 10;
return [Math.max(textWidth, 100), height]; // 高度设为60px(适配两行文本)
5 months ago
},
6 months ago
5 months ago
label: {
position: 'inside',
show: true,
align: 'center',
verticalAlign: 'middle',
fontSize: 12,
lineHeight: 20,
5 months ago
color: '#fff',
formatter: params => {
4 weeks ago
const childText = params.data.quota >= 0 ? `${params.data.quota}` : '';
5 months ago
// 去掉模板字符串缩进,用\n换行,避免多余空白
4 weeks ago
return `${params.data.partCode}\n${params.name}${
childText ? '\n' + childText : ''
}`;
5 months ago
},
},
},
],
};
// 使用制定的配置项和数据显示图表
mapBoxEchart.setOption(option, true);
// // 窗口大小改变时,重新渲染图表
window.addEventListener(
'resize',
function () {
mapBoxEchart.resize();
6 months ago
},
5 months ago
200
);
// 4. 核心:监听点击事件,实现label跳转
mapBoxEchart.on('click', params => {
// 过滤条件:仅点击节点(label/text)时触发,排除连接线等
if (params.componentType === 'series' && params.seriesType === 'tree' && params.data) {
window.open(`${params.data.docLink}`, '_blank');
5 months ago
}
});
},
},
};
6 months ago
</script>
<style lang="scss" scoped>
.form-box {
// height: 700px;
height: calc(100vh - 60px - 40px - 10px - 90px - 31px);
}
.form-bom {
height: calc(100vh - 60px - 40px - 10px - 90px - 31px);
width: '100%';
background: #f0f2f5;
6 months ago
}
5 months ago
</style>