实现密炼物料种类配置关联解析功能,新增种类查找表加载与解析接口,优化选料弹窗层级与刷新功能,增强用户体验与系统稳定性。
This commit is contained in:
@@ -56,6 +56,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 高层级业务弹窗(如混炼示方选料 z-index 1500)打开时,顶部提示需置于弹窗之上
|
||||
.ant-message,
|
||||
.ant-notification {
|
||||
z-index: 2200 !important;
|
||||
}
|
||||
|
||||
// =======================================
|
||||
// ============ [sjl] 按钮组样式 ==========
|
||||
// =======================================
|
||||
|
||||
@@ -130,7 +130,39 @@ function normalizeTreeSelectNodes(nodes: unknown): Recordable[] {
|
||||
}
|
||||
|
||||
/** 加载 MES 物料分类树:根下物料大类 + 各物料小类(供密炼物料/混炼示方选料复用) */
|
||||
export async function loadMesMaterialCategoryTreeData(): Promise<MesMaterialCategoryTreeLoadResult> {
|
||||
let mesMaterialCategoryTreeCache: MesMaterialCategoryTreeLoadResult | null = null;
|
||||
let mesMaterialCategoryTreeLoading: Promise<MesMaterialCategoryTreeLoadResult> | null = null;
|
||||
|
||||
export function hasMesMaterialCategoryTreeCache() {
|
||||
return !!(mesMaterialCategoryTreeCache?.minors?.length || mesMaterialCategoryTreeCache?.majors?.length);
|
||||
}
|
||||
|
||||
export function clearMesMaterialCategoryTreeCache() {
|
||||
mesMaterialCategoryTreeCache = null;
|
||||
mesMaterialCategoryTreeLoading = null;
|
||||
}
|
||||
|
||||
export async function loadMesMaterialCategoryTreeData(forceReload = false): Promise<MesMaterialCategoryTreeLoadResult> {
|
||||
if (!forceReload && mesMaterialCategoryTreeCache) {
|
||||
return mesMaterialCategoryTreeCache;
|
||||
}
|
||||
if (!forceReload && mesMaterialCategoryTreeLoading) {
|
||||
return mesMaterialCategoryTreeLoading;
|
||||
}
|
||||
mesMaterialCategoryTreeLoading = fetchMesMaterialCategoryTreeData()
|
||||
.then((result) => {
|
||||
if (result.minors.length || result.majors.length) {
|
||||
mesMaterialCategoryTreeCache = result;
|
||||
}
|
||||
return result;
|
||||
})
|
||||
.finally(() => {
|
||||
mesMaterialCategoryTreeLoading = null;
|
||||
});
|
||||
return mesMaterialCategoryTreeLoading;
|
||||
}
|
||||
|
||||
async function fetchMesMaterialCategoryTreeData(): Promise<MesMaterialCategoryTreeLoadResult> {
|
||||
// 优先 loadTreeRoot(与密炼物料列表页一致,已验证可用)
|
||||
try {
|
||||
const treeRes = await loadTreeData({ async: false, pcode: MATERIAL_ROOT_CODE });
|
||||
|
||||
@@ -11,12 +11,18 @@ enum Api {
|
||||
importExcel = '/xslmes/mesXslMixerMaterialKindCfg/importExcel',
|
||||
exportXls = '/xslmes/mesXslMixerMaterialKindCfg/exportXls',
|
||||
queryById = '/xslmes/mesXslMixerMaterialKindCfg/queryById',
|
||||
kindLookup = '/xslmes/mesXslMixerMaterialKindCfg/kindLookup',
|
||||
resolveKind = '/xslmes/mesXslMixerMaterialKindCfg/resolveKind',
|
||||
}
|
||||
|
||||
export const list = (params) => defHttp.get({ url: Api.list, params });
|
||||
|
||||
export const queryById = (params) => defHttp.get({ url: Api.queryById, params });
|
||||
|
||||
export const loadKindLookup = (params?) => defHttp.get({ url: Api.kindLookup, params });
|
||||
|
||||
export const resolveKind = (params) => defHttp.get({ url: Api.resolveKind, params });
|
||||
|
||||
export const expandLines = (params) => defHttp.get({ url: Api.expandLines, params });
|
||||
|
||||
export const addBatch = (params) => defHttp.post({ url: Api.addBatch, params }, { successMessageMode: 'none' });
|
||||
|
||||
@@ -967,52 +967,135 @@ export function sanitizeMixingMaterialPickerHiddenCategoryIds(allMinorIds: strin
|
||||
}
|
||||
//update-end---author:cursor ---date:20260525 for:【XSLMES-20260525-A50】选料弹窗小类树为空时重置隐藏配置-----------
|
||||
|
||||
/** 解析混炼示方明细种类:小类勾选胶料则显示「胶料」,否则显示小类名 */
|
||||
export function resolveMixingMaterialKindFromCategory(isRubber?: unknown, minorName?: string) {
|
||||
if (isRubber === '1' || isRubber === 1 || isRubber === true) {
|
||||
return '胶料';
|
||||
//update-begin---author:cursor ---date:20260525 for:【XSLMES-20260525-A52】混炼示方种类改读密炼物料种类配置-----------
|
||||
export interface MixerMaterialKindLookup {
|
||||
byRefId: Record<string, string>;
|
||||
byRefCode: Record<string, string>;
|
||||
rubberKindName?: string;
|
||||
}
|
||||
|
||||
export const EMPTY_MIXER_MATERIAL_KIND_LOOKUP: MixerMaterialKindLookup = {
|
||||
byRefId: {},
|
||||
byRefCode: {},
|
||||
rubberKindName: '胶料',
|
||||
};
|
||||
|
||||
let mixingMaterialKindLookupCache: MixerMaterialKindLookup | null = null;
|
||||
let mixingMaterialKindLookupPromise: Promise<MixerMaterialKindLookup> | null = null;
|
||||
|
||||
/** 加载密炼物料种类配置查找表(带内存缓存) */
|
||||
export async function loadMixingMaterialKindLookup(forceReload = false): Promise<MixerMaterialKindLookup> {
|
||||
if (!forceReload && mixingMaterialKindLookupCache) {
|
||||
return mixingMaterialKindLookupCache;
|
||||
}
|
||||
if (!forceReload && mixingMaterialKindLookupPromise) {
|
||||
return mixingMaterialKindLookupPromise;
|
||||
}
|
||||
mixingMaterialKindLookupPromise = (async () => {
|
||||
try {
|
||||
const { loadKindLookup } = await import('../mesXslMixerMaterialKindCfg/MesXslMixerMaterialKindCfg.api');
|
||||
const raw = await loadKindLookup();
|
||||
const lookup: MixerMaterialKindLookup = {
|
||||
byRefId: raw?.byRefId || {},
|
||||
byRefCode: raw?.byRefCode || {},
|
||||
rubberKindName: raw?.rubberKindName || '胶料',
|
||||
};
|
||||
mixingMaterialKindLookupCache = lookup;
|
||||
return lookup;
|
||||
} catch {
|
||||
return EMPTY_MIXER_MATERIAL_KIND_LOOKUP;
|
||||
} finally {
|
||||
mixingMaterialKindLookupPromise = null;
|
||||
}
|
||||
})();
|
||||
return mixingMaterialKindLookupPromise;
|
||||
}
|
||||
|
||||
/** 清除种类配置缓存(配置变更后可调用) */
|
||||
export function clearMixingMaterialKindLookupCache() {
|
||||
mixingMaterialKindLookupCache = null;
|
||||
mixingMaterialKindLookupPromise = null;
|
||||
}
|
||||
|
||||
function matchKindFromLookup(lookup: MixerMaterialKindLookup | null | undefined, key?: string) {
|
||||
if (!lookup || key == null || String(key).trim() === '') {
|
||||
return '';
|
||||
}
|
||||
const normalized = String(key).trim();
|
||||
if (lookup.byRefId?.[normalized]) {
|
||||
return lookup.byRefId[normalized];
|
||||
}
|
||||
if (lookup.byRefCode?.[normalized]) {
|
||||
return lookup.byRefCode[normalized];
|
||||
}
|
||||
const lower = normalized.toLowerCase();
|
||||
if (lookup.byRefCode?.[lower]) {
|
||||
return lookup.byRefCode[lower];
|
||||
}
|
||||
for (const [code, kindName] of Object.entries(lookup.byRefCode || {})) {
|
||||
if (code && normalized.includes(code)) {
|
||||
return kindName;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/** 解析混炼示方明细种类:称量方式优先,其次物料小类 ID,最后小类名称兜底 */
|
||||
export function resolveMixingMaterialKindFromLookup(
|
||||
lookup: MixerMaterialKindLookup | null | undefined,
|
||||
weighMode?: string,
|
||||
minorCategoryId?: string,
|
||||
minorCategoryName?: string,
|
||||
) {
|
||||
const fromWeighMode = matchKindFromLookup(lookup, weighMode);
|
||||
if (fromWeighMode) {
|
||||
return fromWeighMode;
|
||||
}
|
||||
const fromMinorId = matchKindFromLookup(lookup, minorCategoryId);
|
||||
if (fromMinorId) {
|
||||
return fromMinorId;
|
||||
}
|
||||
if (minorCategoryName != null && String(minorCategoryName).trim() !== '') {
|
||||
return String(minorCategoryName).trim();
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/** @deprecated 保留兼容,请改用 resolveMixingMaterialKindFromLookup */
|
||||
export function resolveMixingMaterialKindFromCategory(_isRubber?: unknown, minorName?: string) {
|
||||
return minorName != null && String(minorName).trim() !== '' ? String(minorName).trim() : '';
|
||||
}
|
||||
|
||||
/** @deprecated 保留兼容,请改用 resolveMixingMaterialKindFromLookup */
|
||||
export function resolveMixingMaterialKindFromWeighMode(_weighMode?: string) {
|
||||
return '';
|
||||
}
|
||||
|
||||
/** 选料确认时种类:读密炼物料种类配置表 */
|
||||
export function resolveMixingMaterialKindForPicker(
|
||||
lookup: MixerMaterialKindLookup | null | undefined,
|
||||
weighMode: string | undefined,
|
||||
minorCategoryId?: string,
|
||||
minorCategoryName?: string,
|
||||
) {
|
||||
return resolveMixingMaterialKindFromLookup(lookup, weighMode, minorCategoryId, minorCategoryName);
|
||||
}
|
||||
//update-end---author:cursor ---date:20260525 for:【XSLMES-20260525-A52】混炼示方种类改读密炼物料种类配置-----------
|
||||
|
||||
//update-begin---author:cursor ---date:20260525 for:【XSLMES-20260525-A50】选料弹窗自动/人工称量列与种类映射-----------
|
||||
/** 与配合示方「自动/人工」列相同字典 */
|
||||
export const MIXING_MATERIAL_PICKER_WEIGH_MODE_DICT = 'xslmes_formula_spec_weigh_mode';
|
||||
|
||||
/** 选料弹窗表格列(隐藏 ERP 编号,新增仅本次有效的自动/人工称量) */
|
||||
/** 选料弹窗表格列(隐藏 ERP 编号,新增种类列与自动/人工称量) */
|
||||
export const mixingMaterialPickerTableColumns: BasicColumn[] = [
|
||||
{ title: '物料编码', align: 'center', width: 120, dataIndex: 'materialCode' },
|
||||
{ title: '物料名称', align: 'center', width: 160, dataIndex: 'materialName' },
|
||||
{ title: '自动/人工称量', align: 'center', width: 132, dataIndex: 'pickerWeighMode' },
|
||||
{ title: '种类', align: 'center', width: 100, dataIndex: 'pickerMaterialKind' },
|
||||
{ title: '物料大类', align: 'center', width: 120, dataIndex: 'majorCategoryId_dictText' },
|
||||
{ title: '物料小类', align: 'center', width: 120, dataIndex: 'minorCategoryId_dictText' },
|
||||
{ title: '物料描述', align: 'center', width: 180, ellipsis: true, dataIndex: 'materialDesc' },
|
||||
];
|
||||
|
||||
/** 配合示方称量方式 -> 混炼示方种类(与后端 resolveWeighModeMaterialKind 一致) */
|
||||
export function resolveMixingMaterialKindFromWeighMode(weighMode?: string) {
|
||||
if (weighMode == null || String(weighMode).trim() === '') {
|
||||
return '';
|
||||
}
|
||||
const normalized = String(weighMode).trim();
|
||||
const lower = normalized.toLowerCase();
|
||||
if (lower.startsWith('auto') || normalized.includes('自动')) {
|
||||
return '自动';
|
||||
}
|
||||
if (lower === 'manual' || normalized.includes('人工')) {
|
||||
return '人工';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/** 选料确认时种类:称量方式优先,否则按小类胶料/小类名 */
|
||||
export function resolveMixingMaterialKindForPicker(weighMode: string | undefined, isRubber?: unknown, minorName?: string) {
|
||||
const fromWeighMode = resolveMixingMaterialKindFromWeighMode(weighMode);
|
||||
if (fromWeighMode) {
|
||||
return fromWeighMode;
|
||||
}
|
||||
return resolveMixingMaterialKindFromCategory(isRubber, minorName);
|
||||
}
|
||||
//update-end---author:cursor ---date:20260525 for:【XSLMES-20260525-A50】选料弹窗自动/人工称量列与种类映射-----------
|
||||
|
||||
/** 选择密炼物料后回填混炼示方橡胶及配合剂明细行 */
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
v-model:open="popoverOpen"
|
||||
trigger="click"
|
||||
placement="bottomRight"
|
||||
:getPopupContainer="getPopoverContainer"
|
||||
:overlayClassName="`${prefixCls}__popover`"
|
||||
@open-change="handleOpenChange"
|
||||
>
|
||||
@@ -14,7 +15,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<template #content>
|
||||
<Spin :spinning="loading">
|
||||
<Spin :spinning="loading || refreshing">
|
||||
<div v-if="!loading && !groupedCategories.length" :class="`${prefixCls}__empty`">
|
||||
暂无物料小类,请确认分类字典 XSLMES_MATERIAL 已配置
|
||||
</div>
|
||||
@@ -35,15 +36,16 @@
|
||||
</div>
|
||||
</Spin>
|
||||
<div :class="`${prefixCls}__footer`">
|
||||
<a-button size="small" :disabled="loading || !allCategoryIds.length" @click="handleReset">重置</a-button>
|
||||
<a-button size="small" type="primary" :disabled="loading || !allCategoryIds.length" @click="handleSave">保存</a-button>
|
||||
<a-button size="small" :loading="refreshing" :disabled="loading" @click="handleRefresh">刷新</a-button>
|
||||
<div :class="`${prefixCls}__footer-actions`">
|
||||
<a-button size="small" :disabled="loading || refreshing || !allCategoryIds.length" @click="handleReset">重置</a-button>
|
||||
<a-button size="small" type="primary" :disabled="loading || refreshing || !allCategoryIds.length" @click="handleSave">保存</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<a-tooltip title="小类展示设置">
|
||||
<a-button size="small" class="mixing-material-category-setting-btn" :disabled="loading" @click.stop>
|
||||
<Icon icon="ant-design:setting-outlined" />
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
<a-button size="small" class="mixing-material-category-setting-btn" :disabled="loading" title="小类展示设置">
|
||||
<Icon icon="ant-design:setting-outlined" />
|
||||
</a-button>
|
||||
</Popover>
|
||||
</template>
|
||||
|
||||
@@ -71,13 +73,21 @@
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
refreshing: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:hiddenCategoryIds', 'change']);
|
||||
const emit = defineEmits(['update:hiddenCategoryIds', 'change', 'refresh']);
|
||||
|
||||
const popoverOpen = ref(false);
|
||||
const draftVisibleIds = ref<string[]>([]);
|
||||
|
||||
function getPopoverContainer() {
|
||||
return document.body;
|
||||
}
|
||||
|
||||
const allCategoryIds = computed(() => (props.categories || []).map((item) => item.id));
|
||||
|
||||
//update-begin---author:cursor ---date:20260525 for:【XSLMES-20260525-A50】选料弹窗小类设置按大类分组展示-----------
|
||||
@@ -156,6 +166,12 @@
|
||||
draftVisibleIds.value = [...allCategoryIds.value];
|
||||
}
|
||||
|
||||
//update-begin---author:cursor ---date:20260525 for:【XSLMES-20260525-A52】小类设置刷新分类字典-----------
|
||||
function handleRefresh() {
|
||||
emit('refresh');
|
||||
}
|
||||
//update-end---author:cursor ---date:20260525 for:【XSLMES-20260525-A52】小类设置刷新分类字典-----------
|
||||
|
||||
function handleSave() {
|
||||
const visibleSet = new Set(draftVisibleIds.value.map(String));
|
||||
const hidden = allCategoryIds.value.filter((id) => !visibleSet.has(String(id)));
|
||||
@@ -175,6 +191,8 @@
|
||||
|
||||
<style lang="less">
|
||||
.mixing-material-category-setting__popover {
|
||||
z-index: 1600 !important;
|
||||
|
||||
.ant-popover-inner-content {
|
||||
width: 320px;
|
||||
max-width: 80vw;
|
||||
@@ -213,9 +231,16 @@
|
||||
|
||||
.mixing-material-category-setting__footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
padding-top: 8px;
|
||||
border-top: 1px solid var(--border-color-base, #f0f0f0);
|
||||
}
|
||||
|
||||
.mixing-material-category-setting__footer-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
<BasicModal
|
||||
v-bind="$attrs"
|
||||
title="选择密炼物料"
|
||||
:width="1180"
|
||||
:getContainer="getModalContainer"
|
||||
:width="1280"
|
||||
:zIndex="1500"
|
||||
wrapClassName="mixing-material-picker-modal-wrap"
|
||||
@register="registerModal"
|
||||
@ok="handleOk"
|
||||
>
|
||||
@@ -21,7 +22,9 @@
|
||||
v-model:hiddenCategoryIds="hiddenCategoryIds"
|
||||
:categories="allMinorCategories"
|
||||
:loading="treeLoading"
|
||||
:refreshing="categoryRefreshing"
|
||||
@change="handleCategoryVisibilityChange"
|
||||
@refresh="handleRefreshCategoryTree"
|
||||
/>
|
||||
</div>
|
||||
<div class="mixing-material-picker-body">
|
||||
@@ -55,6 +58,9 @@
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="column.dataIndex === 'pickerMaterialKind'">
|
||||
{{ resolvePickerMaterialKind(record) }}
|
||||
</template>
|
||||
</template>
|
||||
</BasicTable>
|
||||
</div>
|
||||
@@ -64,19 +70,20 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, onMounted, ref, watch } from 'vue';
|
||||
import { computed, ref, watch } from 'vue';
|
||||
import { Spin } from 'ant-design-vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { BasicTable, useTable } from '/@/components/Table';
|
||||
import { BasicTree } from '/@/components/Tree';
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { loadMesMaterialCategoryTreeData } from '/@/views/system/category/category.constants';
|
||||
import { loadMesMaterialCategoryTreeData, hasMesMaterialCategoryTreeCache } from '/@/views/system/category/category.constants';
|
||||
import { list as mixerList, queryById as queryMixerById } from '/@/views/mes/material/MesMixerMaterial.api';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue';
|
||||
import MesXslMixingMaterialCategorySetting from './MesXslMixingMaterialCategorySetting.vue';
|
||||
import {
|
||||
applyMixingMaterialFromSelection,
|
||||
EMPTY_MIXER_MATERIAL_KIND_LOOKUP,
|
||||
loadMixingMaterialKindLookup,
|
||||
loadMixingMaterialPickerHiddenCategoryIds,
|
||||
MIXING_MATERIAL_PICKER_WEIGH_MODE_DICT,
|
||||
mixingMaterialPickerTableColumns,
|
||||
@@ -84,6 +91,7 @@
|
||||
sanitizeMixingMaterialPickerHiddenCategoryIds,
|
||||
saveMixingMaterialPickerHiddenCategoryIds,
|
||||
type MixingMaterialPickerCategoryItem,
|
||||
type MixerMaterialKindLookup,
|
||||
} from '../MesXslMixingSpec.data';
|
||||
import type { KeyType } from '/@/components/Tree/src/types/tree';
|
||||
|
||||
@@ -100,15 +108,13 @@
|
||||
const selectedCategoryKeys = ref<KeyType[]>([TREE_ALL]);
|
||||
const expandedCategoryKeys = ref<KeyType[]>([TREE_ALL]);
|
||||
const selectedRow = ref<Recordable | null>(null);
|
||||
const categoryRubberMap = ref<Record<string, boolean>>({});
|
||||
const kindLookup = ref<MixerMaterialKindLookup>(EMPTY_MIXER_MATERIAL_KIND_LOOKUP);
|
||||
const pickerWeighModeMap = ref<Record<string, string>>({});
|
||||
const pickerInitializing = ref(false);
|
||||
const categoryRefreshing = ref(false);
|
||||
|
||||
const hiddenCategoryIdSet = computed(() => new Set(hiddenCategoryIds.value.map(String)));
|
||||
|
||||
function getModalContainer() {
|
||||
return document.body;
|
||||
}
|
||||
|
||||
function getSelectPopupContainer() {
|
||||
return document.body;
|
||||
}
|
||||
@@ -179,7 +185,7 @@
|
||||
pagination: { pageSize: 10 },
|
||||
canResize: false,
|
||||
showIndexColumn: true,
|
||||
immediate: true,
|
||||
immediate: false,
|
||||
beforeFetch: (params) => {
|
||||
const next = { ...params, ...selectedCategoryFilter.value };
|
||||
const kw = keyword.value?.trim();
|
||||
@@ -200,10 +206,12 @@
|
||||
|
||||
//update-begin---author:cursor ---date:20260525 for:【XSLMES-20260525-A50】选料弹窗打开时初始化(对齐其他SelectModal)-----------
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async () => {
|
||||
setModalProps({ zIndex: 1500 });
|
||||
await initPickerModal();
|
||||
});
|
||||
|
||||
async function initPickerModal() {
|
||||
pickerInitializing.value = true;
|
||||
selectedRow.value = null;
|
||||
keyword.value = '';
|
||||
pickerWeighModeMap.value = {};
|
||||
@@ -211,38 +219,26 @@
|
||||
hiddenCategoryIds.value = loadMixingMaterialPickerHiddenCategoryIds();
|
||||
selectedCategoryKeys.value = [TREE_ALL];
|
||||
setModalProps({ confirmLoading: false });
|
||||
await loadMaterialCategoryTree();
|
||||
reloadTable();
|
||||
//update-begin---author:cursor ---date:20260525 for:【XSLMES-20260525-A52】选料弹窗先加载左侧树再查右侧列表-----------
|
||||
try {
|
||||
await loadMaterialCategoryTree();
|
||||
kindLookup.value = await loadMixingMaterialKindLookup(false);
|
||||
reloadTable();
|
||||
} finally {
|
||||
pickerInitializing.value = false;
|
||||
}
|
||||
//update-end---author:cursor ---date:20260525 for:【XSLMES-20260525-A52】选料弹窗先加载左侧树再查右侧列表-----------
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadMaterialCategoryTree();
|
||||
});
|
||||
//update-end---author:cursor ---date:20260525 for:【XSLMES-20260525-A50】选料弹窗打开时初始化(对齐其他SelectModal)-----------
|
||||
|
||||
async function loadMaterialCategoryTree() {
|
||||
treeLoading.value = true;
|
||||
async function loadMaterialCategoryTree(forceReload = false) {
|
||||
const hasCachedTree = !forceReload && (hasMesMaterialCategoryTreeCache() || rawCategoryTree.value.length > 0);
|
||||
if (forceReload || !hasCachedTree) {
|
||||
treeLoading.value = true;
|
||||
}
|
||||
try {
|
||||
const { majors, minors, treeNodes } = await loadMesMaterialCategoryTreeData();
|
||||
rawCategoryTree.value = treeNodes;
|
||||
allMajorCategories.value = majors;
|
||||
allMinorCategories.value = minors;
|
||||
|
||||
const sanitizedHidden = sanitizeMixingMaterialPickerHiddenCategoryIds(
|
||||
minors.map((item) => item.id),
|
||||
hiddenCategoryIds.value,
|
||||
);
|
||||
if (sanitizedHidden.length !== hiddenCategoryIds.value.length) {
|
||||
hiddenCategoryIds.value = sanitizedHidden;
|
||||
saveMixingMaterialPickerHiddenCategoryIds(sanitizedHidden);
|
||||
}
|
||||
|
||||
categoryRubberMap.value = {};
|
||||
syncExpandedCategoryKeys();
|
||||
|
||||
if (!minors.length) {
|
||||
createMessage.warning('未加载到物料小类,请确认分类字典根编码 XSLMES_MATERIAL 及其下级分类已配置。');
|
||||
}
|
||||
const { majors, minors, treeNodes } = await loadMesMaterialCategoryTreeData(forceReload);
|
||||
applyMaterialCategoryTreeData(majors, minors, treeNodes);
|
||||
} catch {
|
||||
rawCategoryTree.value = [];
|
||||
allMajorCategories.value = [];
|
||||
@@ -253,6 +249,60 @@
|
||||
}
|
||||
}
|
||||
|
||||
function applyMaterialCategoryTreeData(
|
||||
majors: Array<{ id: string; name: string; minors: MixingMaterialPickerCategoryItem[] }>,
|
||||
minors: MixingMaterialPickerCategoryItem[],
|
||||
treeNodes: Recordable[],
|
||||
) {
|
||||
rawCategoryTree.value = treeNodes;
|
||||
allMajorCategories.value = majors;
|
||||
allMinorCategories.value = minors;
|
||||
|
||||
const sanitizedHidden = sanitizeMixingMaterialPickerHiddenCategoryIds(
|
||||
minors.map((item) => item.id),
|
||||
hiddenCategoryIds.value,
|
||||
);
|
||||
if (sanitizedHidden.length !== hiddenCategoryIds.value.length) {
|
||||
hiddenCategoryIds.value = sanitizedHidden;
|
||||
saveMixingMaterialPickerHiddenCategoryIds(sanitizedHidden);
|
||||
}
|
||||
|
||||
syncExpandedCategoryKeys();
|
||||
|
||||
if (!minors.length) {
|
||||
createMessage.warning('未加载到物料小类,请确认分类字典根编码 XSLMES_MATERIAL 及其下级分类已配置。');
|
||||
}
|
||||
}
|
||||
|
||||
//update-begin---author:cursor ---date:20260525 for:【XSLMES-20260525-A52】小类设置刷新分类字典-----------
|
||||
/** 刷新分类字典:重新拉取小类列表,新增小类默认隐藏,勾选保存后展示到左侧树 */
|
||||
async function handleRefreshCategoryTree() {
|
||||
if (categoryRefreshing.value) {
|
||||
return;
|
||||
}
|
||||
const previousIds = new Set(allMinorCategories.value.map((item) => String(item.id)));
|
||||
categoryRefreshing.value = true;
|
||||
try {
|
||||
await loadMaterialCategoryTree(true);
|
||||
const newMinorIds = allMinorCategories.value
|
||||
.filter((item) => !previousIds.has(String(item.id)))
|
||||
.map((item) => String(item.id));
|
||||
if (newMinorIds.length) {
|
||||
const nextHidden = sanitizeMixingMaterialPickerHiddenCategoryIds(
|
||||
allMinorCategories.value.map((item) => item.id),
|
||||
[...hiddenCategoryIds.value.map(String), ...newMinorIds],
|
||||
);
|
||||
hiddenCategoryIds.value = nextHidden;
|
||||
createMessage.success(`已刷新,发现 ${newMinorIds.length} 个新小类,请勾选后点击保存`);
|
||||
} else {
|
||||
createMessage.success('已刷新,分类无变化');
|
||||
}
|
||||
} finally {
|
||||
categoryRefreshing.value = false;
|
||||
}
|
||||
}
|
||||
//update-end---author:cursor ---date:20260525 for:【XSLMES-20260525-A52】小类设置刷新分类字典-----------
|
||||
|
||||
function reloadTable() {
|
||||
reload();
|
||||
}
|
||||
@@ -280,6 +330,9 @@
|
||||
|
||||
function onCategorySelect(keys: KeyType[]) {
|
||||
selectedCategoryKeys.value = keys?.length ? keys : [TREE_ALL];
|
||||
if (pickerInitializing.value) {
|
||||
return;
|
||||
}
|
||||
reloadTable();
|
||||
}
|
||||
|
||||
@@ -309,25 +362,17 @@
|
||||
reloadTable();
|
||||
}
|
||||
|
||||
async function resolveKindForMaterial(material: Recordable, weighMode?: string) {
|
||||
function resolvePickerMaterialKind(material: Recordable) {
|
||||
const weighMode = getPickerWeighMode(material?.id);
|
||||
const minorId = material?.minorCategoryId ? String(material.minorCategoryId) : '';
|
||||
const minorName = material?.minorCategoryId_dictText || '';
|
||||
if (!minorId) {
|
||||
return resolveMixingMaterialKindForPicker(weighMode, false, minorName);
|
||||
}
|
||||
if (categoryRubberMap.value[minorId] === undefined) {
|
||||
try {
|
||||
const cat = await defHttp.get<Recordable>({ url: '/sys/category/queryById', params: { id: minorId } });
|
||||
categoryRubberMap.value[minorId] = cat?.isRubber === '1' || cat?.isRubber === 1;
|
||||
} catch {
|
||||
categoryRubberMap.value[minorId] = false;
|
||||
}
|
||||
}
|
||||
return resolveMixingMaterialKindForPicker(
|
||||
weighMode,
|
||||
categoryRubberMap.value[minorId] ? '1' : '0',
|
||||
minorName,
|
||||
);
|
||||
return resolveMixingMaterialKindForPicker(kindLookup.value, weighMode, minorId, minorName);
|
||||
}
|
||||
|
||||
function resolveKindForMaterial(material: Recordable, weighMode?: string) {
|
||||
const minorId = material?.minorCategoryId ? String(material.minorCategoryId) : '';
|
||||
const minorName = material?.minorCategoryId_dictText || '';
|
||||
return resolveMixingMaterialKindForPicker(kindLookup.value, weighMode, minorId, minorName);
|
||||
}
|
||||
|
||||
async function handleOk() {
|
||||
@@ -347,7 +392,7 @@
|
||||
}
|
||||
const weighMode = getPickerWeighMode(row.id);
|
||||
const payload: Recordable = { ...row, pickerWeighMode: weighMode };
|
||||
const materialKind = await resolveKindForMaterial(row, weighMode);
|
||||
const materialKind = resolveKindForMaterial(row, weighMode);
|
||||
applyMixingMaterialFromSelection(payload, row, materialKind);
|
||||
emit('select', payload);
|
||||
closeModal();
|
||||
@@ -399,6 +444,11 @@
|
||||
</style>
|
||||
|
||||
<style lang="less">
|
||||
/* 嵌套在全屏混炼示方弹窗之上,避免偶发被父弹窗遮挡 */
|
||||
.mixing-material-picker-modal-wrap {
|
||||
z-index: 1500 !important;
|
||||
}
|
||||
|
||||
/* 下拉挂到 body,避免表格 overflow 裁剪;层级高于 Modal */
|
||||
.mixing-material-picker-weigh-mode-dropdown {
|
||||
z-index: 2100 !important;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
:defaultFullscreen="true"
|
||||
wrapClassName="mixing-spec-modal-wrap"
|
||||
@register="registerModal"
|
||||
@cancel="closeNestedPickers"
|
||||
@ok="handleSubmit"
|
||||
>
|
||||
<template #title>{{ title }}</template>
|
||||
@@ -882,9 +883,18 @@ const [registerForm, { resetFields, setFieldsValue, validate, setProps }] = useF
|
||||
});
|
||||
|
||||
//update-begin---author:cursor ---date:20260522 for:【XSLMES-20260522-A33】混炼示方主表选择弹窗-----------
|
||||
const [registerMachineModal, { openModal: openMachineModalInner }] = useModal();
|
||||
const [registerIssueNumberModal, { openModal: openIssueNumberModalInner }] = useModal();
|
||||
const [registerMixingMaterialModal, { openModal: openMixingMaterialModalInner }] = useModal();
|
||||
const [registerMachineModal, { openModal: openMachineModalInner, closeModal: closeMachineModal }] = useModal();
|
||||
const [registerIssueNumberModal, { openModal: openIssueNumberModalInner, closeModal: closeIssueNumberModal }] = useModal();
|
||||
const [registerMixingMaterialModal, { openModal: openMixingMaterialModalInner, closeModal: closeMixingMaterialModal, setModalProps: setMixingMaterialModalProps }] = useModal();
|
||||
|
||||
//update-begin---author:cursor ---date:20260525 for:【XSLMES-20260525-A52】关闭混炼示方弹窗时同步关闭嵌套选料弹窗-----------
|
||||
function closeNestedPickers() {
|
||||
closeMixingMaterialModal();
|
||||
closeMachineModal();
|
||||
closeIssueNumberModal();
|
||||
materialPickerRow.value = null;
|
||||
}
|
||||
//update-end---author:cursor ---date:20260525 for:【XSLMES-20260525-A52】关闭混炼示方弹窗时同步关闭嵌套选料弹窗-----------
|
||||
|
||||
function openMachinePicker() {
|
||||
if (!showFooter.value) {
|
||||
@@ -924,7 +934,10 @@ function openMixingMaterialPicker(row: Recordable) {
|
||||
return;
|
||||
}
|
||||
materialPickerRow.value = row;
|
||||
//update-begin---author:cursor ---date:20260525 for:【XSLMES-20260525-A52】选料弹窗层级高于全屏父弹窗-----------
|
||||
setMixingMaterialModalProps({ zIndex: 1500 });
|
||||
openMixingMaterialModalInner(true, { picker: true, ts: Date.now() });
|
||||
//update-end---author:cursor ---date:20260525 for:【XSLMES-20260525-A52】选料弹窗层级高于全屏父弹窗-----------
|
||||
}
|
||||
|
||||
function onMixingMaterialSelect(payload: Recordable | null) {
|
||||
|
||||
Reference in New Issue
Block a user