194 lines
6.2 KiB
Vue
194 lines
6.2 KiB
Vue
<template>
|
||
<BasicModal
|
||
v-bind="$attrs"
|
||
title="生成混炼示方"
|
||
:width="880"
|
||
destroyOnClose
|
||
@register="registerModal"
|
||
@ok="handleConfirm"
|
||
>
|
||
<a-spin :spinning="loading">
|
||
<div v-if="rubberName" class="generate-mixing-tip">
|
||
胶料名称:<strong>{{ rubberName }}</strong>,混合段数:<strong>{{ mixingStages }}</strong>,确认后将按「预览行 × 机台」生成混炼示方。
|
||
</div>
|
||
<a-table
|
||
:columns="tableColumns"
|
||
:data-source="tableRows"
|
||
:pagination="false"
|
||
row-key="rowKey"
|
||
size="small"
|
||
bordered
|
||
>
|
||
<template #bodyCell="{ column, record }">
|
||
<template v-if="column.dataIndex === 'machines'">
|
||
<div class="machine-cell">
|
||
<a-input
|
||
:value="formatMachineNames(record.machines)"
|
||
readonly
|
||
placeholder="请点击选择机台(可多选)"
|
||
class="machine-picker-input"
|
||
@click="openMachinePicker(record)"
|
||
/>
|
||
<a-button type="link" size="small" @click="openMachinePicker(record)">选择</a-button>
|
||
</div>
|
||
</template>
|
||
</template>
|
||
</a-table>
|
||
<div v-if="totalGenerateCount > 0" class="generate-mixing-summary">
|
||
预计生成 <strong>{{ totalGenerateCount }}</strong> 条混炼示方
|
||
</div>
|
||
</a-spin>
|
||
<MesXslEquipmentLedgerMultiSelectModal @register="registerMachineModal" @select="onMachineSelect" />
|
||
</BasicModal>
|
||
</template>
|
||
|
||
<script lang="ts" setup>
|
||
import { computed, ref } from 'vue';
|
||
import { BasicModal, useModal, useModalInner } from '/@/components/Modal';
|
||
import { useMessage } from '/@/hooks/web/useMessage';
|
||
import MesXslEquipmentLedgerMultiSelectModal from '/@/views/xslmes/mesXslEquipInspectConfig/components/MesXslEquipmentLedgerMultiSelectModal.vue';
|
||
import { buildMixingGeneratePreview, generateMixingSpec } from '../MesXslFormulaSpec.api';
|
||
|
||
const emit = defineEmits(['register', 'success']);
|
||
|
||
const { createMessage } = useMessage();
|
||
const loading = ref(false);
|
||
const formulaSpecId = ref('');
|
||
const rubberName = ref('');
|
||
const mixingStages = ref(0);
|
||
const tableRows = ref<Recordable[]>([]);
|
||
const editingRowKey = ref<number | null>(null);
|
||
|
||
function formatStageCountText(record: Recordable) {
|
||
const current = record?.stageIndex;
|
||
const total = mixingStages.value;
|
||
if (total > 0) {
|
||
return `${current ?? ''}/${total}`;
|
||
}
|
||
return current != null ? String(current) : '';
|
||
}
|
||
|
||
const tableColumns = [
|
||
{ title: '示方编号', dataIndex: 'specCode', width: 220 },
|
||
{ title: '段数', dataIndex: 'stageIndex', width: 72, customRender: ({ record }) => formatStageCountText(record) },
|
||
{ title: '机台', dataIndex: 'machines' },
|
||
];
|
||
|
||
const totalGenerateCount = computed(() =>
|
||
tableRows.value.reduce((sum, row) => sum + (row.machines?.length || 0), 0),
|
||
);
|
||
|
||
const [registerMachineModal, { openModal: openMachineModalInner }] = useModal();
|
||
|
||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||
formulaSpecId.value = data?.formulaSpecId || '';
|
||
tableRows.value = [];
|
||
rubberName.value = '';
|
||
mixingStages.value = 0;
|
||
setModalProps({ confirmLoading: false });
|
||
if (!formulaSpecId.value) {
|
||
createMessage.warning('未指定配合示方');
|
||
return;
|
||
}
|
||
loading.value = true;
|
||
try {
|
||
const preview = await buildMixingGeneratePreview({ formulaSpecId: formulaSpecId.value });
|
||
rubberName.value = preview?.rubberName || '';
|
||
mixingStages.value = preview?.mixingStages || 0;
|
||
tableRows.value = (preview?.items || []).map((item: Recordable) => ({
|
||
rowKey: item.rowKey,
|
||
specCode: item.specCode,
|
||
stageIndex: item.stageIndex,
|
||
aSegmentIndex: item.aSegmentIndex,
|
||
stepType: item.stepType,
|
||
machines: [],
|
||
}));
|
||
if (!tableRows.value.length) {
|
||
createMessage.warning('无可生成的混炼段,请检查混合段数');
|
||
}
|
||
} finally {
|
||
loading.value = false;
|
||
}
|
||
});
|
||
|
||
function formatMachineNames(machines: Recordable[] = []) {
|
||
return machines.map((m) => m.machineName).filter(Boolean).join('、');
|
||
}
|
||
|
||
function openMachinePicker(record: Recordable) {
|
||
editingRowKey.value = record.rowKey;
|
||
openMachineModalInner(true, { selectedMachines: record.machines || [] });
|
||
}
|
||
|
||
function onMachineSelect(machines: Recordable[]) {
|
||
const key = editingRowKey.value;
|
||
if (key == null) {
|
||
return;
|
||
}
|
||
const row = tableRows.value.find((r) => r.rowKey === key);
|
||
if (row) {
|
||
row.machines = machines || [];
|
||
}
|
||
editingRowKey.value = null;
|
||
}
|
||
|
||
async function handleConfirm() {
|
||
if (!formulaSpecId.value) {
|
||
createMessage.warning('未指定配合示方');
|
||
return;
|
||
}
|
||
if (!tableRows.value.length) {
|
||
createMessage.warning('无可生成的混炼段');
|
||
return;
|
||
}
|
||
const emptyMachine = tableRows.value.find((r) => !r.machines?.length);
|
||
if (emptyMachine) {
|
||
createMessage.warning(`请为示方「${emptyMachine.specCode}」选择机台`);
|
||
return;
|
||
}
|
||
setModalProps({ confirmLoading: true });
|
||
try {
|
||
const res = await generateMixingSpec({
|
||
formulaSpecId: formulaSpecId.value,
|
||
rows: tableRows.value.map((r) => ({
|
||
specCode: r.specCode,
|
||
stageIndex: r.stageIndex,
|
||
aSegmentIndex: r.aSegmentIndex,
|
||
stepType: r.stepType,
|
||
machines: (r.machines || []).map((m: Recordable) => ({
|
||
machineId: m.machineId,
|
||
machineName: m.machineName,
|
||
})),
|
||
})),
|
||
});
|
||
const count = Number(res?.count ?? 0);
|
||
createMessage.success(count > 0 ? `成功生成 ${count} 条混炼示方` : '生成成功');
|
||
closeModal();
|
||
emit('success');
|
||
} finally {
|
||
setModalProps({ confirmLoading: false });
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="less" scoped>
|
||
.generate-mixing-tip {
|
||
margin-bottom: 12px;
|
||
color: rgba(0, 0, 0, 0.65);
|
||
}
|
||
.machine-cell {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 4px;
|
||
.machine-picker-input {
|
||
flex: 1;
|
||
cursor: pointer;
|
||
}
|
||
}
|
||
.generate-mixing-summary {
|
||
margin-top: 12px;
|
||
text-align: right;
|
||
color: rgba(0, 0, 0, 0.85);
|
||
}
|
||
</style>
|