<template>
<div ref="tableRef">
<div v-if="isLoading" class="loading-container">
<div class="spinner"></div>
<p>数据加载中...</p>
</div>
<el-table
v-else
:data="currentPageData"
show-overflow-tooltip="false"
style="width: 100%; font-size: 12px; white-space: pre;"
:header-cell-style="headerCellStyle"
:cell-class-name="tableCellClassName"
:cell-style="tableCellStyle"
ref="page17Ref"
@row-click="handleRowClick"
>
<el-table-column label="STEPSEQ" prop="STEPSEQ" align="center" ></el-table-column>
<el-table-column label="Recipe" prop="RECIPE" align="center" min-width="100" ></el-table-column>
<el-table-column v-for= "item in Column" :label="item.One" align="center">
<el-table-column v-for="(subColumn,subIndex) in item.Two" :key="subIndex" :prop="'BL' + subColumn.replace(/\s+/g,'')" align="center">
<template #header>
<div>{{ subColumn }}</div>
</template>
<template #default="scope">
<span>
{{ scope.row['BL' + subColumn.replace(/\s+/g,'')] }}
</span>
</template>
</el-table-column>
</el-table-column>
<el-table-column label="Recipe Count" prop="RECIPE_COUNT" align="center" min-width="100" > </el-table-column>
</el-table>
<el-pagination
v-if="totalPages > 1"
:current-page="currentPage"
:page-size="pageSize"
:total="scanrateData.length"
@current-change="handlePageChange"
layout="pre, pager, next"
/>
<!-- 行点击弹窗 -->
<el-dialog
v-model="dialogVisible"
width="600px"
@close="handleCancel"
>
<template #header>
<div class="dialog header">
<strong>FeedBack</strong>
</div>
</template>
<el-form label-width="130px" :model="formData">
<el-form-item label="STEPSEQ">
<el-input v-model="formData.STEPSEQ" disabled />
</el-form-item>
<el-form-item label="RECIPE">
<el-input v-model="formData.RECIPE" disabled />
</el-form-item>
<el-form-item label="DUEDAY">
<el-date-picker
v-model="formData.DUEDAY"
type="date"
placeholder="选择日期"
format="YYYY/MM/DD"
value-format="YYYY/MM/DD"
style="width: 100%"
/>
</el-form-item>
<el-form-item label="STATUS">
<el-select v-model="formData.STATUS" style="width: 100%">
<el-option label="Ongoing" value="Ongoing" />
<el-option label="Closed" value="Closed" />
</el-select>
</el-form-item>
<el-form-item label="Owner">
<el-input v-model="formData.Owner" disabled />
</el-form-item>
<el-form-item label="ROOTCAUSE">
<el-input
v-model="formData.ROOTCAUSE"
type="textarea"
:rows="4"
placeholder="周一13点至周五9点开放feedback..."
/>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="handleCancel">取消</el-button>
<!-- <el-button type="primary" @click="handleSubmit">提交</el-button> -->
<el-button type="primary" @click="handleSubmit" :disabled="!isSubmitAllowed">提交</el-button>
</template>
</el-dialog>
</div>
</template> const getMinWidth = (columnName: string) => {
if (columnName === 'Recipe Count') return MIN_WIDTH_CONFIG.Recipecount;
if (columnName === 'Recipe') return MIN_WIDTH_CONFIG.Recipe;
if (columnName === 'Capability') return MIN_WIDTH_CONFIG.Capability;
if (columnName === 'Root Cause') return MIN_WIDTH_CONFIG.Rootcause;
if (columnName === 'Due Day') return MIN_WIDTH_CONFIG.Dueday;
if (columnName === 'Owner') return MIN_WIDTH_CONFIG.Owner;
if (columnName === 'Status') return MIN_WIDTH_CONFIG.Status;
// if (columnName === 'HLCount') return MIN_WIDTH_CONFIG.HLCount;
return 75; // 其他列不设最小宽度
};
/**
* 无子列的单列 - 最大宽度计算(非Recipe/Capability生效)
* @param columnName 列名
*/
// const getSingleMaxWidth = (columnName: string) => {
// console.log("getSingleMaxWidth被调用");
// if (columnName !== 'Recipe' && columnName !== 'Capability') {
// return DEFAULT_MAX_WIDTH;
// }
// return undefined; // Recipe/Capability不设最大宽度
// 动态表头样式生成
const generateDynamicStyles = () => {
const allColors = new Set<string>();
Column.value.forEach(column => {
if (column.color) allColors.add(column.color);
column.subColumns?.forEach(subCol => {
if (subCol.color) allColors.add(subCol.color);
});
});
let styles = '';
allColors.forEach(color => {
const className = `header-color-${color.replace(/[^\w]/g, '')}`;
const isDark = isColorDark(color);
styles += `
.el-table__header .${className} {
background-color: ${color} !important;
color: ${isDark ? 'white' : 'black'} !important;
}
`;
});
if (styleElement.value) {
styleElement.value.textContent = styles;
} else {
const style = document.createElement('style');
style.type = 'text/css';
style.textContent = styles;
document.head.appendChild(style);
styleElement.value = style;
}
};
const isColorDark = (color: string) => {
const rgbMatch = color.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
if (rgbMatch) {
const [r, g, b] = rgbMatch.slice(1).map(Number);
const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
return luminance < 0.5;
}
if (color.startsWith('#')) {
const hex = color.slice(1);
const r = parseInt(hex.substring(0, 2), 16);
const g = parseInt(hex.substring(2, 4), 16);
const b = parseInt(hex.substring(4, 6), 16);
const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
return luminance < 0.5;
}
return false;
}; const extraColumns = [
{ COLUMN: 'Root Cause', prop: 'ROOTCAUSE'},
{ COLUMN: 'Due Day', prop: 'DUEDAY'},
{ COLUMN: 'Owner', prop: 'OWNER'},
{ COLUMN: 'Status', prop: 'STATUS'},
// { COLUMN: 'HLCount', prop: 'HLCOUNT'}
];
extraColumns.forEach((col) => {
const columnConfig: any = {
One: col.COLUMN,
prop: col.prop,
color: 'rgb(47, 117, 181)'
};
if(col.COLUMN === 'Due Day'){
columnConfig.formatter = (row, column, value) => formatDateOnly(value);
}
Column.value.push(columnConfig);
});
isActiveRule.value = conf[0].config.isActiveRule;
console.log("ColumnOne", ColumnOne.value);
console.log("ColumnTwo", ColumnTwo.value);
generateDynamicStyles();
} catch (err) {
console.error('获取报表配置失败', err);
}
}
const fetchTableData = async () => {
try {
const res = await request({
method: 'get',
url: '/api/prodeport?type=IReview'
});
// console.log('HprodRecipeDFI数据', res.data);
recipedfiData.value = res.data.RecipeDFI_result;
recipedifReviewData.value =res.data.DFIReview_result
console.log('recipedreview',recipedifReviewData.value);
} catch (err){
console.error('获取HprodRecipeDFI数据失败', err);
}
}
const headerCellClassName = ({ column }: { column: any }) => {
if (!column.columnKey) return '';
const keyParts = column.columnKey.split('-');
const colIndex = parseInt(keyParts[1]);
if (isNaN(colIndex)) return '';
const currentColumn = Column.value[colIndex];
if (!currentColumn) return '';
if (keyParts[0] === 'parent' || keyParts[0] === 'single') {
return currentColumn.color ? `header-color-${currentColumn.color.replace(/[^\w]/g, '')}` : '';
}
if (keyParts[0] === 'child') {
const subIndex = parseInt(keyParts[2]);
if (!isNaN(subIndex) && currentColumn.subColumns[subIndex]) {
const subColor = currentColumn.subColumns[subIndex].color;
return subColor ? `header-color-${subColor.replace(/[^\w]/g, '')}` : '';
}
}
return '';
};
onMounted(async () => {
try {
isLoading.value = true;
await Promise.all([fetchReportConfig(), fetchTableData()]);
// insertClickVolume();
} catch (err) {
console.log('数据加载失败', err);
} finally {
isLoading.value = false;
}
});
const abnormalData = computed(() => {
return recipedfiData.value.filter(item => {
return [...machineColumn.value].some(key => abnormalList.includes(item[key]))
})
})
const mergedabnormalData = computed(() => {
return abnormalData.value.map(item =>{
const matchReview =recipedifReviewData.value.find(review =>
review.STSEQ===item.STSEQ &&
review.REPE===item.RIPE &&
review.SYSUPDATETIME===item.SYSUPDATETIME
);
return {
...item,
DUEDAY:matchReview?.DUEDAY|| null,
ROOTCAUSE:matchReview?.ROOTCAUSE|| null,
OWNER:matchReview?.OWNER||null,
STATUS:matchReview?.STATUS||null,
}
})
})
console.log('recipeRiew',recipedifReviewData);
console.log('abnormaldata',abnormalData);
console.log('mergedabnormalData',mergedabnormalData);
//第一个分页数据
const currentPageData = computed(() => {
const start = (currentPage.value - 1) * pageSize.value;
// console.log('abnormalData',abnormalData.value);
// return abnormalData.value.slice(start, start + pageSize.value);
// return mergedabnormalData.value.slice(start, start + pageSize.value);
return mergedabnormalData.value.slice(start, start + pageSize.value);
});运行后为什么extracolumn的数据不显示