fix(mes): 修复选择器筛选和单选弹窗

- 将 MES 通知单/工作站选择器的单选场景改为 radio
- 保留多选场景的 checkbox 与跨页 reserve 行为
- 修复生产工单选择器固定 status/type 参数丢失问题
- 修复空值选择器悬停时误展示清空图标的问题
- 按页面/操作步骤补充 ZSXQ 反馈与验收记录

关联星球:https://t.zsxq.com/dtLd8
pull/361/MERGE
YunaiV 2026-06-13 11:00:30 +08:00
parent f89b0365a1
commit bc6e7cf622
27 changed files with 720 additions and 462 deletions

View File

@ -30,69 +30,80 @@ const emit = defineEmits<{
const open = ref(false); //
const multiple = ref(true); //
const syncingSingleSelection = ref(false); //
const selectedRows = ref<MesMdWorkstationApi.Workstation[]>([]); //
const preSelectedIds = ref<number[]>([]); //
/** 单选模式下同步 VXE 勾选状态 */
async function syncSingleSelection(row?: MesMdWorkstationApi.Workstation) {
syncingSingleSelection.value = true;
await nextTick();
await gridApi.grid.clearCheckboxRow();
if (row) {
await gridApi.grid.setCheckboxRow(row, true);
}
await nextTick();
syncingSingleSelection.value = false;
/** 获取多选记录,包含 VXE reserve 跨页记录 */
function getMultipleSelectedRows() {
const selectedMap = new Map<number, MesMdWorkstationApi.Workstation>();
const records = [
...(gridApi.grid.getCheckboxReserveRecords?.() ?? []),
...(gridApi.grid.getCheckboxRecords?.() ?? []),
] as MesMdWorkstationApi.Workstation[];
records.forEach((row) => {
const rowId = row.id;
if (rowId !== undefined) {
selectedMap.set(rowId, row);
}
});
return [...selectedMap.values()];
}
/** 处理勾选变化,单选模式只保留最后一条 */
async function handleCheckboxChange({
checked,
records,
/** 处理多选勾选变化 */
function handleCheckboxSelectChange() {
if (!multiple.value) {
return;
}
selectedRows.value = getMultipleSelectedRows();
}
/** 处理单选切换 */
function handleRadioChange(row: MesMdWorkstationApi.Workstation) {
selectedRows.value = [row];
}
/** 多选模式下切换行勾选 */
async function toggleMultipleRow(row: MesMdWorkstationApi.Workstation) {
const selected = gridApi.grid.isCheckedByCheckboxRow(row);
await gridApi.grid.setCheckboxRow(row, !selected);
selectedRows.value = getMultipleSelectedRows();
}
/** 处理行双击:单选直接确认,多选切换勾选 */
async function handleCellDblclick({
row,
}: {
checked: boolean;
records: MesMdWorkstationApi.Workstation[];
row?: MesMdWorkstationApi.Workstation;
row: MesMdWorkstationApi.Workstation;
}) {
if (syncingSingleSelection.value) {
if (multiple.value) {
await toggleMultipleRow(row);
return;
}
if (!multiple.value) {
const selected = checked && row ? [row] : [];
selectedRows.value = selected;
await syncSingleSelection(selected[0]);
return;
}
selectedRows.value = records;
}
/** 处理全选变化 */
function handleCheckboxAll({
records,
}: {
records: MesMdWorkstationApi.Workstation[];
}) {
if (syncingSingleSelection.value) {
return;
}
selectedRows.value = records;
selectedRows.value = [row];
await gridApi.grid.setRadioRow(row);
handleConfirm();
}
/** 回显预选工作站 */
function applyPreSelection() {
async function applyPreSelection() {
if (preSelectedIds.value.length === 0) {
return;
}
const rows = gridApi.grid.getData() as MesMdWorkstationApi.Workstation[];
for (const row of rows) {
if (row.id && preSelectedIds.value.includes(row.id)) {
gridApi.grid.setCheckboxRow(row, true);
if (!multiple.value) {
selectedRows.value = [row];
}
if (row.id === undefined || !preSelectedIds.value.includes(row.id)) {
continue;
}
if (multiple.value) {
await gridApi.grid.setCheckboxRow(row, true);
} else {
await gridApi.grid.setRadioRow(row);
selectedRows.value = [row];
return;
}
}
if (multiple.value) {
selectedRows.value = getMultipleSelectedRows();
}
}
@ -101,7 +112,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
schema: useWorkstationSelectGridFormSchema(),
},
gridOptions: {
columns: useWorkstationSelectGridColumns(),
columns: useWorkstationSelectGridColumns(true),
height: 520,
keepSource: true,
checkboxConfig: {
@ -109,6 +120,10 @@ const [Grid, gridApi] = useVbenVxeGrid({
range: true,
reserve: true,
},
radioConfig: {
highlight: true,
trigger: 'row',
},
proxyConfig: {
ajax: {
query: async ({ page }, formValues) => {
@ -131,8 +146,12 @@ const [Grid, gridApi] = useVbenVxeGrid({
},
} as VxeTableGridOptions<MesMdWorkstationApi.Workstation>,
gridEvents: {
checkboxAll: handleCheckboxAll,
checkboxChange: handleCheckboxChange,
cellDblclick: handleCellDblclick,
checkboxAll: handleCheckboxSelectChange,
checkboxChange: handleCheckboxSelectChange,
radioChange: ({ row }: { row: MesMdWorkstationApi.Workstation }) => {
handleRadioChange(row);
},
},
});
@ -140,6 +159,8 @@ const [Grid, gridApi] = useVbenVxeGrid({
async function resetQueryState() {
selectedRows.value = [];
await gridApi.grid.clearCheckboxRow();
await gridApi.grid.clearCheckboxReserve();
await gridApi.grid.clearRadioRow();
await gridApi.formApi.resetForm();
if (props.processId) {
await gridApi.formApi.setFieldValue('processId', props.processId);
@ -155,10 +176,13 @@ async function openModal(
multiple.value = options?.multiple ?? true;
preSelectedIds.value = selectedIds || [];
await nextTick();
gridApi.setGridOptions({
columns: useWorkstationSelectGridColumns(multiple.value),
});
await resetQueryState();
await gridApi.query();
await nextTick();
applyPreSelection();
await applyPreSelection();
}
/** 关闭工作站选择弹窗 */

View File

@ -44,6 +44,7 @@ const showClear = computed(
props.allowClear &&
!props.disabled &&
hovering.value &&
props.modelValue !== undefined &&
props.modelValue !== null,
);

View File

@ -320,9 +320,11 @@ export function useWorkstationSelectGridFormSchema(): VbenFormSchema[] {
}
/** 工作站选择弹窗的字段 */
export function useWorkstationSelectGridColumns(): VxeTableGridOptions<MesMdWorkstationApi.Workstation>['columns'] {
export function useWorkstationSelectGridColumns(
multiple = true,
): VxeTableGridOptions<MesMdWorkstationApi.Workstation>['columns'] {
return [
{ type: 'checkbox', width: 50 },
{ type: multiple ? 'checkbox' : 'radio', width: 50 },
{
field: 'code',
title: '工作站编码',

View File

@ -37,7 +37,7 @@ const selectedRows = ref<MesProWorkOrderApi.WorkOrder[]>([]); // 已选工单列
const preSelectedIds = ref<number[]>([]); //
const typeTip = computed(() => {
if (props.type === null) {
if (props.type === undefined) {
return '';
}
return `仅展示【${getDictLabel(DICT_TYPE.MES_PRO_WORK_ORDER_TYPE, props.type)}】类型的工单`;
@ -61,6 +61,9 @@ function getMultipleSelectedRows() {
/** 处理多选勾选变化 */
function handleCheckboxSelectChange() {
if (!multiple.value) {
return;
}
selectedRows.value = getMultipleSelectedRows();
}
@ -137,8 +140,9 @@ const [Grid, gridApi] = useVbenVxeGrid({
return await getWorkOrderPage({
pageNo: page.currentPage,
pageSize: page.pageSize,
type: props.type,
...formValues,
...(props.status === undefined ? {} : { status: props.status }),
...(props.type === undefined ? {} : { type: props.type }),
});
},
},
@ -169,7 +173,7 @@ async function resetQueryState() {
await gridApi.grid.clearCheckboxReserve();
await gridApi.grid.clearRadioRow();
await gridApi.formApi.resetForm();
if (props.status !== null) {
if (props.status !== undefined) {
await gridApi.formApi.setFieldValue('status', props.status);
}
}

View File

@ -49,6 +49,7 @@ const showClear = computed(
props.allowClear &&
!props.disabled &&
hovering.value &&
props.modelValue !== undefined &&
props.modelValue !== null,
);

View File

@ -19,7 +19,6 @@ const emit = defineEmits<{
const open = ref(false); //
const multiple = ref(false); //
const fixedStatus = ref<number>(); //
const syncingSingleSelection = ref(false); //
const selectedRows = ref<MesWmArrivalNoticeApi.ArrivalNotice[]>([]); //
const preSelectedIds = ref<number[]>([]); //
@ -57,10 +56,12 @@ function useSearchSchema(): VbenFormSchema[] {
}
/** 表格字段 */
function useGridColumns(): VxeTableGridOptions<MesWmArrivalNoticeApi.ArrivalNotice>['columns'] {
function useGridColumns(
multipleSelect = false,
): VxeTableGridOptions<MesWmArrivalNoticeApi.ArrivalNotice>['columns'] {
return [
{
type: 'checkbox',
type: multipleSelect ? 'checkbox' : 'radio',
width: 50,
},
{
@ -101,65 +102,77 @@ function useGridColumns(): VxeTableGridOptions<MesWmArrivalNoticeApi.ArrivalNoti
];
}
/** 单选模式下同步 VXE 勾选状态,避免跨页残留多选 */
async function syncSingleSelection(row?: MesWmArrivalNoticeApi.ArrivalNotice) {
syncingSingleSelection.value = true;
await nextTick();
await gridApi.grid.clearCheckboxRow();
if (row) {
await gridApi.grid.setCheckboxRow(row, true);
}
await nextTick();
syncingSingleSelection.value = false;
/** 获取多选记录,包含 VXE reserve 跨页记录 */
function getMultipleSelectedRows() {
const selectedMap = new Map<number, MesWmArrivalNoticeApi.ArrivalNotice>();
const records = [
...(gridApi.grid.getCheckboxReserveRecords?.() ?? []),
...(gridApi.grid.getCheckboxRecords?.() ?? []),
] as MesWmArrivalNoticeApi.ArrivalNotice[];
records.forEach((row) => {
const rowId = row.id;
if (rowId !== undefined) {
selectedMap.set(rowId, row);
}
});
return [...selectedMap.values()];
}
/** 处理勾选变化,单选模式只保留最后一条 */
async function handleCheckboxChange({
checked,
records,
/** 处理多选勾选变化 */
function handleCheckboxSelectChange() {
if (!multiple.value) {
return;
}
selectedRows.value = getMultipleSelectedRows();
}
/** 处理单选切换 */
function handleRadioChange(row: MesWmArrivalNoticeApi.ArrivalNotice) {
selectedRows.value = [row];
}
/** 多选模式下切换行勾选 */
async function toggleMultipleRow(row: MesWmArrivalNoticeApi.ArrivalNotice) {
const selected = gridApi.grid.isCheckedByCheckboxRow(row);
await gridApi.grid.setCheckboxRow(row, !selected);
selectedRows.value = getMultipleSelectedRows();
}
/** 处理行双击:单选直接确认,多选切换勾选 */
async function handleCellDblclick({
row,
}: {
checked: boolean;
records: MesWmArrivalNoticeApi.ArrivalNotice[];
row?: MesWmArrivalNoticeApi.ArrivalNotice;
row: MesWmArrivalNoticeApi.ArrivalNotice;
}) {
if (syncingSingleSelection.value) {
if (multiple.value) {
await toggleMultipleRow(row);
return;
}
if (!multiple.value) {
const selected = checked && row ? [row] : [];
selectedRows.value = selected;
await syncSingleSelection(selected[0]);
return;
}
selectedRows.value = records;
}
/** 处理全选变化 */
function handleCheckboxAll({
records,
}: {
records: MesWmArrivalNoticeApi.ArrivalNotice[];
}) {
if (syncingSingleSelection.value) {
return;
}
selectedRows.value = records;
selectedRows.value = [row];
await gridApi.grid.setRadioRow(row);
handleConfirm();
}
/** 回显预选通知单 */
function applyPreSelection() {
async function applyPreSelection() {
if (preSelectedIds.value.length === 0) {
return;
}
const rows = gridApi.grid.getData() as MesWmArrivalNoticeApi.ArrivalNotice[];
for (const row of rows) {
if (row.id && preSelectedIds.value.includes(row.id)) {
gridApi.grid.setCheckboxRow(row, true);
if (!multiple.value) {
selectedRows.value = [row];
}
if (row.id === undefined || !preSelectedIds.value.includes(row.id)) {
continue;
}
if (multiple.value) {
await gridApi.grid.setCheckboxRow(row, true);
} else {
await gridApi.grid.setRadioRow(row);
selectedRows.value = [row];
return;
}
}
if (multiple.value) {
selectedRows.value = getMultipleSelectedRows();
}
}
@ -168,7 +181,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
schema: useSearchSchema(),
},
gridOptions: {
columns: useGridColumns(),
columns: useGridColumns(false),
height: 520,
keepSource: true,
checkboxConfig: {
@ -176,6 +189,10 @@ const [Grid, gridApi] = useVbenVxeGrid({
range: true,
reserve: true,
},
radioConfig: {
highlight: true,
trigger: 'row',
},
proxyConfig: {
ajax: {
query: async ({ page }, formValues) => {
@ -198,8 +215,12 @@ const [Grid, gridApi] = useVbenVxeGrid({
},
} as VxeTableGridOptions<MesWmArrivalNoticeApi.ArrivalNotice>,
gridEvents: {
checkboxAll: handleCheckboxAll,
checkboxChange: handleCheckboxChange,
cellDblclick: handleCellDblclick,
checkboxAll: handleCheckboxSelectChange,
checkboxChange: handleCheckboxSelectChange,
radioChange: ({ row }: { row: MesWmArrivalNoticeApi.ArrivalNotice }) => {
handleRadioChange(row);
},
},
});
@ -207,6 +228,8 @@ const [Grid, gridApi] = useVbenVxeGrid({
async function resetQueryState() {
selectedRows.value = [];
await gridApi.grid.clearCheckboxRow();
await gridApi.grid.clearCheckboxReserve();
await gridApi.grid.clearRadioRow();
await gridApi.formApi.resetForm();
}
@ -220,10 +243,13 @@ async function openModal(
fixedStatus.value = options?.status;
preSelectedIds.value = selectedIds || [];
await nextTick();
gridApi.setGridOptions({
columns: useGridColumns(multiple.value),
});
await resetQueryState();
await gridApi.query();
await nextTick();
applyPreSelection();
await applyPreSelection();
}
/** 关闭通知单选择弹窗 */

View File

@ -47,6 +47,7 @@ const showClear = computed(
props.allowClear &&
!props.disabled &&
hovering.value &&
props.modelValue !== undefined &&
props.modelValue !== null,
);

View File

@ -21,7 +21,6 @@ const emit = defineEmits<{
const open = ref(false); //
const multiple = ref(false); //
const fixedStatus = ref<number>(); //
const syncingSingleSelection = ref(false); //
const selectedRows = ref<MesWmSalesNoticeApi.SalesNotice[]>([]); //
const preSelectedIds = ref<number[]>([]); //
@ -84,10 +83,12 @@ function useSearchSchema(hasFixedStatus: boolean): VbenFormSchema[] {
}
/** 表格字段 */
function useGridColumns(): VxeTableGridOptions<MesWmSalesNoticeApi.SalesNotice>['columns'] {
function useGridColumns(
multipleSelect = false,
): VxeTableGridOptions<MesWmSalesNoticeApi.SalesNotice>['columns'] {
return [
{
type: 'checkbox',
type: multipleSelect ? 'checkbox' : 'radio',
width: 50,
},
{
@ -128,65 +129,77 @@ function useGridColumns(): VxeTableGridOptions<MesWmSalesNoticeApi.SalesNotice>[
];
}
/** 单选模式下同步 VXE 勾选状态,避免跨页残留多选 */
async function syncSingleSelection(row?: MesWmSalesNoticeApi.SalesNotice) {
syncingSingleSelection.value = true;
await nextTick();
await gridApi.grid.clearCheckboxRow();
if (row) {
await gridApi.grid.setCheckboxRow(row, true);
}
await nextTick();
syncingSingleSelection.value = false;
/** 获取多选记录,包含 VXE reserve 跨页记录 */
function getMultipleSelectedRows() {
const selectedMap = new Map<number, MesWmSalesNoticeApi.SalesNotice>();
const records = [
...(gridApi.grid.getCheckboxReserveRecords?.() ?? []),
...(gridApi.grid.getCheckboxRecords?.() ?? []),
] as MesWmSalesNoticeApi.SalesNotice[];
records.forEach((row) => {
const rowId = row.id;
if (rowId !== undefined) {
selectedMap.set(rowId, row);
}
});
return [...selectedMap.values()];
}
/** 处理勾选变化,单选模式只保留最后一条 */
async function handleCheckboxChange({
checked,
records,
/** 处理多选勾选变化 */
function handleCheckboxSelectChange() {
if (!multiple.value) {
return;
}
selectedRows.value = getMultipleSelectedRows();
}
/** 处理单选切换 */
function handleRadioChange(row: MesWmSalesNoticeApi.SalesNotice) {
selectedRows.value = [row];
}
/** 多选模式下切换行勾选 */
async function toggleMultipleRow(row: MesWmSalesNoticeApi.SalesNotice) {
const selected = gridApi.grid.isCheckedByCheckboxRow(row);
await gridApi.grid.setCheckboxRow(row, !selected);
selectedRows.value = getMultipleSelectedRows();
}
/** 处理行双击:单选直接确认,多选切换勾选 */
async function handleCellDblclick({
row,
}: {
checked: boolean;
records: MesWmSalesNoticeApi.SalesNotice[];
row?: MesWmSalesNoticeApi.SalesNotice;
row: MesWmSalesNoticeApi.SalesNotice;
}) {
if (syncingSingleSelection.value) {
if (multiple.value) {
await toggleMultipleRow(row);
return;
}
if (!multiple.value) {
const selected = checked && row ? [row] : [];
selectedRows.value = selected;
await syncSingleSelection(selected[0]);
return;
}
selectedRows.value = records;
}
/** 处理全选变化 */
function handleCheckboxAll({
records,
}: {
records: MesWmSalesNoticeApi.SalesNotice[];
}) {
if (syncingSingleSelection.value) {
return;
}
selectedRows.value = records;
selectedRows.value = [row];
await gridApi.grid.setRadioRow(row);
handleConfirm();
}
/** 回显预选通知单 */
function applyPreSelection() {
async function applyPreSelection() {
if (preSelectedIds.value.length === 0) {
return;
}
const rows = gridApi.grid.getData() as MesWmSalesNoticeApi.SalesNotice[];
for (const row of rows) {
if (row.id && preSelectedIds.value.includes(row.id)) {
gridApi.grid.setCheckboxRow(row, true);
if (!multiple.value) {
selectedRows.value = [row];
}
if (row.id === undefined || !preSelectedIds.value.includes(row.id)) {
continue;
}
if (multiple.value) {
await gridApi.grid.setCheckboxRow(row, true);
} else {
await gridApi.grid.setRadioRow(row);
selectedRows.value = [row];
return;
}
}
if (multiple.value) {
selectedRows.value = getMultipleSelectedRows();
}
}
@ -195,7 +208,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
schema: useSearchSchema(false),
},
gridOptions: {
columns: useGridColumns(),
columns: useGridColumns(false),
height: 520,
keepSource: true,
checkboxConfig: {
@ -203,6 +216,10 @@ const [Grid, gridApi] = useVbenVxeGrid({
range: true,
reserve: true,
},
radioConfig: {
highlight: true,
trigger: 'row',
},
proxyConfig: {
ajax: {
query: async ({ page }, formValues) => {
@ -226,8 +243,12 @@ const [Grid, gridApi] = useVbenVxeGrid({
},
} as VxeTableGridOptions<MesWmSalesNoticeApi.SalesNotice>,
gridEvents: {
checkboxAll: handleCheckboxAll,
checkboxChange: handleCheckboxChange,
cellDblclick: handleCellDblclick,
checkboxAll: handleCheckboxSelectChange,
checkboxChange: handleCheckboxSelectChange,
radioChange: ({ row }: { row: MesWmSalesNoticeApi.SalesNotice }) => {
handleRadioChange(row);
},
},
});
@ -235,6 +256,8 @@ const [Grid, gridApi] = useVbenVxeGrid({
async function resetQueryState() {
selectedRows.value = [];
await gridApi.grid.clearCheckboxRow();
await gridApi.grid.clearCheckboxReserve();
await gridApi.grid.clearRadioRow();
await gridApi.formApi.resetForm();
}
@ -249,13 +272,16 @@ async function openModal(
preSelectedIds.value = selectedIds || [];
//
gridApi.formApi.setState({
schema: useSearchSchema(fixedStatus.value !== null),
schema: useSearchSchema(fixedStatus.value !== undefined),
});
await nextTick();
gridApi.setGridOptions({
columns: useGridColumns(multiple.value),
});
await resetQueryState();
await gridApi.query();
await nextTick();
applyPreSelection();
await applyPreSelection();
}
/** 关闭通知单选择弹窗 */

View File

@ -47,6 +47,7 @@ const showClear = computed(
props.allowClear &&
!props.disabled &&
hovering.value &&
props.modelValue !== undefined &&
props.modelValue !== null,
);

View File

@ -30,69 +30,80 @@ const emit = defineEmits<{
const open = ref(false); //
const multiple = ref(true); //
const syncingSingleSelection = ref(false); //
const selectedRows = ref<MesMdWorkstationApi.Workstation[]>([]); //
const preSelectedIds = ref<number[]>([]); //
/** 单选模式下同步 VXE 勾选状态 */
async function syncSingleSelection(row?: MesMdWorkstationApi.Workstation) {
syncingSingleSelection.value = true;
await nextTick();
await gridApi.grid.clearCheckboxRow();
if (row) {
await gridApi.grid.setCheckboxRow(row, true);
}
await nextTick();
syncingSingleSelection.value = false;
/** 获取多选记录,包含 VXE reserve 跨页记录 */
function getMultipleSelectedRows() {
const selectedMap = new Map<number, MesMdWorkstationApi.Workstation>();
const records = [
...(gridApi.grid.getCheckboxReserveRecords?.() ?? []),
...(gridApi.grid.getCheckboxRecords?.() ?? []),
] as MesMdWorkstationApi.Workstation[];
records.forEach((row) => {
const rowId = row.id;
if (rowId !== undefined) {
selectedMap.set(rowId, row);
}
});
return [...selectedMap.values()];
}
/** 处理勾选变化,单选模式只保留最后一条 */
async function handleCheckboxChange({
checked,
records,
/** 处理多选勾选变化 */
function handleCheckboxSelectChange() {
if (!multiple.value) {
return;
}
selectedRows.value = getMultipleSelectedRows();
}
/** 处理单选切换 */
function handleRadioChange(row: MesMdWorkstationApi.Workstation) {
selectedRows.value = [row];
}
/** 多选模式下切换行勾选 */
async function toggleMultipleRow(row: MesMdWorkstationApi.Workstation) {
const selected = gridApi.grid.isCheckedByCheckboxRow(row);
await gridApi.grid.setCheckboxRow(row, !selected);
selectedRows.value = getMultipleSelectedRows();
}
/** 处理行双击:单选直接确认,多选切换勾选 */
async function handleCellDblclick({
row,
}: {
checked: boolean;
records: MesMdWorkstationApi.Workstation[];
row?: MesMdWorkstationApi.Workstation;
row: MesMdWorkstationApi.Workstation;
}) {
if (syncingSingleSelection.value) {
if (multiple.value) {
await toggleMultipleRow(row);
return;
}
if (!multiple.value) {
const selected = checked && row ? [row] : [];
selectedRows.value = selected;
await syncSingleSelection(selected[0]);
return;
}
selectedRows.value = records;
}
/** 处理全选变化 */
function handleCheckboxAll({
records,
}: {
records: MesMdWorkstationApi.Workstation[];
}) {
if (syncingSingleSelection.value) {
return;
}
selectedRows.value = records;
selectedRows.value = [row];
await gridApi.grid.setRadioRow(row);
handleConfirm();
}
/** 回显预选工作站 */
function applyPreSelection() {
async function applyPreSelection() {
if (preSelectedIds.value.length === 0) {
return;
}
const rows = gridApi.grid.getData() as MesMdWorkstationApi.Workstation[];
for (const row of rows) {
if (row.id && preSelectedIds.value.includes(row.id)) {
gridApi.grid.setCheckboxRow(row, true);
if (!multiple.value) {
selectedRows.value = [row];
}
if (row.id === undefined || !preSelectedIds.value.includes(row.id)) {
continue;
}
if (multiple.value) {
await gridApi.grid.setCheckboxRow(row, true);
} else {
await gridApi.grid.setRadioRow(row);
selectedRows.value = [row];
return;
}
}
if (multiple.value) {
selectedRows.value = getMultipleSelectedRows();
}
}
@ -101,7 +112,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
schema: useWorkstationSelectGridFormSchema(),
},
gridOptions: {
columns: useWorkstationSelectGridColumns(),
columns: useWorkstationSelectGridColumns(true),
height: 520,
keepSource: true,
checkboxConfig: {
@ -109,6 +120,10 @@ const [Grid, gridApi] = useVbenVxeGrid({
range: true,
reserve: true,
},
radioConfig: {
highlight: true,
trigger: 'row',
},
proxyConfig: {
ajax: {
query: async ({ page }, formValues) => {
@ -131,8 +146,12 @@ const [Grid, gridApi] = useVbenVxeGrid({
},
} as VxeTableGridOptions<MesMdWorkstationApi.Workstation>,
gridEvents: {
checkboxAll: handleCheckboxAll,
checkboxChange: handleCheckboxChange,
cellDblclick: handleCellDblclick,
checkboxAll: handleCheckboxSelectChange,
checkboxChange: handleCheckboxSelectChange,
radioChange: ({ row }: { row: MesMdWorkstationApi.Workstation }) => {
handleRadioChange(row);
},
},
});
@ -140,6 +159,8 @@ const [Grid, gridApi] = useVbenVxeGrid({
async function resetQueryState() {
selectedRows.value = [];
await gridApi.grid.clearCheckboxRow();
await gridApi.grid.clearCheckboxReserve();
await gridApi.grid.clearRadioRow();
await gridApi.formApi.resetForm();
if (props.processId) {
await gridApi.formApi.setFieldValue('processId', props.processId);
@ -155,10 +176,13 @@ async function openModal(
multiple.value = options?.multiple ?? true;
preSelectedIds.value = selectedIds || [];
await nextTick();
gridApi.setGridOptions({
columns: useWorkstationSelectGridColumns(multiple.value),
});
await resetQueryState();
await gridApi.query();
await nextTick();
applyPreSelection();
await applyPreSelection();
}
/** 关闭工作站选择弹窗 */

View File

@ -44,6 +44,7 @@ const showClear = computed(
props.allowClear &&
!props.disabled &&
hovering.value &&
props.modelValue !== undefined &&
props.modelValue !== null,
);

View File

@ -320,9 +320,11 @@ export function useWorkstationSelectGridFormSchema(): VbenFormSchema[] {
}
/** 工作站选择弹窗的字段 */
export function useWorkstationSelectGridColumns(): VxeTableGridOptions<MesMdWorkstationApi.Workstation>['columns'] {
export function useWorkstationSelectGridColumns(
multiple = true,
): VxeTableGridOptions<MesMdWorkstationApi.Workstation>['columns'] {
return [
{ type: 'checkbox', width: 50 },
{ type: multiple ? 'checkbox' : 'radio', width: 50 },
{
field: 'code',
title: '工作站编码',

View File

@ -37,7 +37,7 @@ const selectedRows = ref<MesProWorkOrderApi.WorkOrder[]>([]); // 已选工单列
const preSelectedIds = ref<number[]>([]); //
const typeTip = computed(() => {
if (props.type === null) {
if (props.type === undefined) {
return '';
}
return `仅展示【${getDictLabel(DICT_TYPE.MES_PRO_WORK_ORDER_TYPE, props.type)}】类型的工单`;
@ -61,6 +61,9 @@ function getMultipleSelectedRows() {
/** 处理多选勾选变化 */
function handleCheckboxSelectChange() {
if (!multiple.value) {
return;
}
selectedRows.value = getMultipleSelectedRows();
}
@ -137,8 +140,9 @@ const [Grid, gridApi] = useVbenVxeGrid({
return await getWorkOrderPage({
pageNo: page.currentPage,
pageSize: page.pageSize,
type: props.type,
...formValues,
...(props.status === undefined ? {} : { status: props.status }),
...(props.type === undefined ? {} : { type: props.type }),
});
},
},
@ -169,7 +173,7 @@ async function resetQueryState() {
await gridApi.grid.clearCheckboxReserve();
await gridApi.grid.clearRadioRow();
await gridApi.formApi.resetForm();
if (props.status !== null) {
if (props.status !== undefined) {
await gridApi.formApi.setFieldValue('status', props.status);
}
}

View File

@ -49,6 +49,7 @@ const showClear = computed(
props.allowClear &&
!props.disabled &&
hovering.value &&
props.modelValue !== undefined &&
props.modelValue !== null,
);

View File

@ -19,7 +19,6 @@ const emit = defineEmits<{
const open = ref(false); //
const multiple = ref(false); //
const fixedStatus = ref<number>(); //
const syncingSingleSelection = ref(false); //
const selectedRows = ref<MesWmArrivalNoticeApi.ArrivalNotice[]>([]); //
const preSelectedIds = ref<number[]>([]); //
@ -57,10 +56,12 @@ function useSearchSchema(): VbenFormSchema[] {
}
/** 表格字段 */
function useGridColumns(): VxeTableGridOptions<MesWmArrivalNoticeApi.ArrivalNotice>['columns'] {
function useGridColumns(
multipleSelect = false,
): VxeTableGridOptions<MesWmArrivalNoticeApi.ArrivalNotice>['columns'] {
return [
{
type: 'checkbox',
type: multipleSelect ? 'checkbox' : 'radio',
width: 50,
},
{
@ -101,65 +102,77 @@ function useGridColumns(): VxeTableGridOptions<MesWmArrivalNoticeApi.ArrivalNoti
];
}
/** 单选模式下同步 VXE 勾选状态,避免跨页残留多选 */
async function syncSingleSelection(row?: MesWmArrivalNoticeApi.ArrivalNotice) {
syncingSingleSelection.value = true;
await nextTick();
await gridApi.grid.clearCheckboxRow();
if (row) {
await gridApi.grid.setCheckboxRow(row, true);
}
await nextTick();
syncingSingleSelection.value = false;
/** 获取多选记录,包含 VXE reserve 跨页记录 */
function getMultipleSelectedRows() {
const selectedMap = new Map<number, MesWmArrivalNoticeApi.ArrivalNotice>();
const records = [
...(gridApi.grid.getCheckboxReserveRecords?.() ?? []),
...(gridApi.grid.getCheckboxRecords?.() ?? []),
] as MesWmArrivalNoticeApi.ArrivalNotice[];
records.forEach((row) => {
const rowId = row.id;
if (rowId !== undefined) {
selectedMap.set(rowId, row);
}
});
return [...selectedMap.values()];
}
/** 处理勾选变化,单选模式只保留最后一条 */
async function handleCheckboxChange({
checked,
records,
/** 处理多选勾选变化 */
function handleCheckboxSelectChange() {
if (!multiple.value) {
return;
}
selectedRows.value = getMultipleSelectedRows();
}
/** 处理单选切换 */
function handleRadioChange(row: MesWmArrivalNoticeApi.ArrivalNotice) {
selectedRows.value = [row];
}
/** 多选模式下切换行勾选 */
async function toggleMultipleRow(row: MesWmArrivalNoticeApi.ArrivalNotice) {
const selected = gridApi.grid.isCheckedByCheckboxRow(row);
await gridApi.grid.setCheckboxRow(row, !selected);
selectedRows.value = getMultipleSelectedRows();
}
/** 处理行双击:单选直接确认,多选切换勾选 */
async function handleCellDblclick({
row,
}: {
checked: boolean;
records: MesWmArrivalNoticeApi.ArrivalNotice[];
row?: MesWmArrivalNoticeApi.ArrivalNotice;
row: MesWmArrivalNoticeApi.ArrivalNotice;
}) {
if (syncingSingleSelection.value) {
if (multiple.value) {
await toggleMultipleRow(row);
return;
}
if (!multiple.value) {
const selected = checked && row ? [row] : [];
selectedRows.value = selected;
await syncSingleSelection(selected[0]);
return;
}
selectedRows.value = records;
}
/** 处理全选变化 */
function handleCheckboxAll({
records,
}: {
records: MesWmArrivalNoticeApi.ArrivalNotice[];
}) {
if (syncingSingleSelection.value) {
return;
}
selectedRows.value = records;
selectedRows.value = [row];
await gridApi.grid.setRadioRow(row);
handleConfirm();
}
/** 回显预选通知单 */
function applyPreSelection() {
async function applyPreSelection() {
if (preSelectedIds.value.length === 0) {
return;
}
const rows = gridApi.grid.getData() as MesWmArrivalNoticeApi.ArrivalNotice[];
for (const row of rows) {
if (row.id && preSelectedIds.value.includes(row.id)) {
gridApi.grid.setCheckboxRow(row, true);
if (!multiple.value) {
selectedRows.value = [row];
}
if (row.id === undefined || !preSelectedIds.value.includes(row.id)) {
continue;
}
if (multiple.value) {
await gridApi.grid.setCheckboxRow(row, true);
} else {
await gridApi.grid.setRadioRow(row);
selectedRows.value = [row];
return;
}
}
if (multiple.value) {
selectedRows.value = getMultipleSelectedRows();
}
}
@ -168,7 +181,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
schema: useSearchSchema(),
},
gridOptions: {
columns: useGridColumns(),
columns: useGridColumns(false),
height: 520,
keepSource: true,
checkboxConfig: {
@ -176,6 +189,10 @@ const [Grid, gridApi] = useVbenVxeGrid({
range: true,
reserve: true,
},
radioConfig: {
highlight: true,
trigger: 'row',
},
proxyConfig: {
ajax: {
query: async ({ page }, formValues) => {
@ -198,8 +215,12 @@ const [Grid, gridApi] = useVbenVxeGrid({
},
} as VxeTableGridOptions<MesWmArrivalNoticeApi.ArrivalNotice>,
gridEvents: {
checkboxAll: handleCheckboxAll,
checkboxChange: handleCheckboxChange,
cellDblclick: handleCellDblclick,
checkboxAll: handleCheckboxSelectChange,
checkboxChange: handleCheckboxSelectChange,
radioChange: ({ row }: { row: MesWmArrivalNoticeApi.ArrivalNotice }) => {
handleRadioChange(row);
},
},
});
@ -207,6 +228,8 @@ const [Grid, gridApi] = useVbenVxeGrid({
async function resetQueryState() {
selectedRows.value = [];
await gridApi.grid.clearCheckboxRow();
await gridApi.grid.clearCheckboxReserve();
await gridApi.grid.clearRadioRow();
await gridApi.formApi.resetForm();
}
@ -220,10 +243,13 @@ async function openModal(
fixedStatus.value = options?.status;
preSelectedIds.value = selectedIds || [];
await nextTick();
gridApi.setGridOptions({
columns: useGridColumns(multiple.value),
});
await resetQueryState();
await gridApi.query();
await nextTick();
applyPreSelection();
await applyPreSelection();
}
/** 关闭通知单选择弹窗 */

View File

@ -47,6 +47,7 @@ const showClear = computed(
props.allowClear &&
!props.disabled &&
hovering.value &&
props.modelValue !== undefined &&
props.modelValue !== null,
);

View File

@ -21,7 +21,6 @@ const emit = defineEmits<{
const open = ref(false); //
const multiple = ref(false); //
const fixedStatus = ref<number>(); //
const syncingSingleSelection = ref(false); //
const selectedRows = ref<MesWmSalesNoticeApi.SalesNotice[]>([]); //
const preSelectedIds = ref<number[]>([]); //
@ -84,10 +83,12 @@ function useSearchSchema(hasFixedStatus: boolean): VbenFormSchema[] {
}
/** 表格字段 */
function useGridColumns(): VxeTableGridOptions<MesWmSalesNoticeApi.SalesNotice>['columns'] {
function useGridColumns(
multipleSelect = false,
): VxeTableGridOptions<MesWmSalesNoticeApi.SalesNotice>['columns'] {
return [
{
type: 'checkbox',
type: multipleSelect ? 'checkbox' : 'radio',
width: 50,
},
{
@ -128,65 +129,77 @@ function useGridColumns(): VxeTableGridOptions<MesWmSalesNoticeApi.SalesNotice>[
];
}
/** 单选模式下同步 VXE 勾选状态,避免跨页残留多选 */
async function syncSingleSelection(row?: MesWmSalesNoticeApi.SalesNotice) {
syncingSingleSelection.value = true;
await nextTick();
await gridApi.grid.clearCheckboxRow();
if (row) {
await gridApi.grid.setCheckboxRow(row, true);
}
await nextTick();
syncingSingleSelection.value = false;
/** 获取多选记录,包含 VXE reserve 跨页记录 */
function getMultipleSelectedRows() {
const selectedMap = new Map<number, MesWmSalesNoticeApi.SalesNotice>();
const records = [
...(gridApi.grid.getCheckboxReserveRecords?.() ?? []),
...(gridApi.grid.getCheckboxRecords?.() ?? []),
] as MesWmSalesNoticeApi.SalesNotice[];
records.forEach((row) => {
const rowId = row.id;
if (rowId !== undefined) {
selectedMap.set(rowId, row);
}
});
return [...selectedMap.values()];
}
/** 处理勾选变化,单选模式只保留最后一条 */
async function handleCheckboxChange({
checked,
records,
/** 处理多选勾选变化 */
function handleCheckboxSelectChange() {
if (!multiple.value) {
return;
}
selectedRows.value = getMultipleSelectedRows();
}
/** 处理单选切换 */
function handleRadioChange(row: MesWmSalesNoticeApi.SalesNotice) {
selectedRows.value = [row];
}
/** 多选模式下切换行勾选 */
async function toggleMultipleRow(row: MesWmSalesNoticeApi.SalesNotice) {
const selected = gridApi.grid.isCheckedByCheckboxRow(row);
await gridApi.grid.setCheckboxRow(row, !selected);
selectedRows.value = getMultipleSelectedRows();
}
/** 处理行双击:单选直接确认,多选切换勾选 */
async function handleCellDblclick({
row,
}: {
checked: boolean;
records: MesWmSalesNoticeApi.SalesNotice[];
row?: MesWmSalesNoticeApi.SalesNotice;
row: MesWmSalesNoticeApi.SalesNotice;
}) {
if (syncingSingleSelection.value) {
if (multiple.value) {
await toggleMultipleRow(row);
return;
}
if (!multiple.value) {
const selected = checked && row ? [row] : [];
selectedRows.value = selected;
await syncSingleSelection(selected[0]);
return;
}
selectedRows.value = records;
}
/** 处理全选变化 */
function handleCheckboxAll({
records,
}: {
records: MesWmSalesNoticeApi.SalesNotice[];
}) {
if (syncingSingleSelection.value) {
return;
}
selectedRows.value = records;
selectedRows.value = [row];
await gridApi.grid.setRadioRow(row);
handleConfirm();
}
/** 回显预选通知单 */
function applyPreSelection() {
async function applyPreSelection() {
if (preSelectedIds.value.length === 0) {
return;
}
const rows = gridApi.grid.getData() as MesWmSalesNoticeApi.SalesNotice[];
for (const row of rows) {
if (row.id && preSelectedIds.value.includes(row.id)) {
gridApi.grid.setCheckboxRow(row, true);
if (!multiple.value) {
selectedRows.value = [row];
}
if (row.id === undefined || !preSelectedIds.value.includes(row.id)) {
continue;
}
if (multiple.value) {
await gridApi.grid.setCheckboxRow(row, true);
} else {
await gridApi.grid.setRadioRow(row);
selectedRows.value = [row];
return;
}
}
if (multiple.value) {
selectedRows.value = getMultipleSelectedRows();
}
}
@ -195,7 +208,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
schema: useSearchSchema(false),
},
gridOptions: {
columns: useGridColumns(),
columns: useGridColumns(false),
height: 520,
keepSource: true,
checkboxConfig: {
@ -203,6 +216,10 @@ const [Grid, gridApi] = useVbenVxeGrid({
range: true,
reserve: true,
},
radioConfig: {
highlight: true,
trigger: 'row',
},
proxyConfig: {
ajax: {
query: async ({ page }, formValues) => {
@ -226,8 +243,12 @@ const [Grid, gridApi] = useVbenVxeGrid({
},
} as VxeTableGridOptions<MesWmSalesNoticeApi.SalesNotice>,
gridEvents: {
checkboxAll: handleCheckboxAll,
checkboxChange: handleCheckboxChange,
cellDblclick: handleCellDblclick,
checkboxAll: handleCheckboxSelectChange,
checkboxChange: handleCheckboxSelectChange,
radioChange: ({ row }: { row: MesWmSalesNoticeApi.SalesNotice }) => {
handleRadioChange(row);
},
},
});
@ -235,6 +256,8 @@ const [Grid, gridApi] = useVbenVxeGrid({
async function resetQueryState() {
selectedRows.value = [];
await gridApi.grid.clearCheckboxRow();
await gridApi.grid.clearCheckboxReserve();
await gridApi.grid.clearRadioRow();
await gridApi.formApi.resetForm();
}
@ -249,13 +272,16 @@ async function openModal(
preSelectedIds.value = selectedIds || [];
//
gridApi.formApi.setState({
schema: useSearchSchema(fixedStatus.value !== null),
schema: useSearchSchema(fixedStatus.value !== undefined),
});
await nextTick();
gridApi.setGridOptions({
columns: useGridColumns(multiple.value),
});
await resetQueryState();
await gridApi.query();
await nextTick();
applyPreSelection();
await applyPreSelection();
}
/** 关闭通知单选择弹窗 */

View File

@ -47,6 +47,7 @@ const showClear = computed(
props.allowClear &&
!props.disabled &&
hovering.value &&
props.modelValue !== undefined &&
props.modelValue !== null,
);

View File

@ -30,69 +30,80 @@ const emit = defineEmits<{
const open = ref(false); //
const multiple = ref(true); //
const syncingSingleSelection = ref(false); //
const selectedRows = ref<MesMdWorkstationApi.Workstation[]>([]); //
const preSelectedIds = ref<number[]>([]); //
/** 单选模式下同步 VXE 勾选状态 */
async function syncSingleSelection(row?: MesMdWorkstationApi.Workstation) {
syncingSingleSelection.value = true;
await nextTick();
await gridApi.grid.clearCheckboxRow();
if (row) {
await gridApi.grid.setCheckboxRow(row, true);
}
await nextTick();
syncingSingleSelection.value = false;
/** 获取多选记录,包含 VXE reserve 跨页记录 */
function getMultipleSelectedRows() {
const selectedMap = new Map<number, MesMdWorkstationApi.Workstation>();
const records = [
...(gridApi.grid.getCheckboxReserveRecords?.() ?? []),
...(gridApi.grid.getCheckboxRecords?.() ?? []),
] as MesMdWorkstationApi.Workstation[];
records.forEach((row) => {
const rowId = row.id;
if (rowId !== undefined) {
selectedMap.set(rowId, row);
}
});
return [...selectedMap.values()];
}
/** 处理勾选变化,单选模式只保留最后一条 */
async function handleCheckboxChange({
checked,
records,
/** 处理多选勾选变化 */
function handleCheckboxSelectChange() {
if (!multiple.value) {
return;
}
selectedRows.value = getMultipleSelectedRows();
}
/** 处理单选切换 */
function handleRadioChange(row: MesMdWorkstationApi.Workstation) {
selectedRows.value = [row];
}
/** 多选模式下切换行勾选 */
async function toggleMultipleRow(row: MesMdWorkstationApi.Workstation) {
const selected = gridApi.grid.isCheckedByCheckboxRow(row);
await gridApi.grid.setCheckboxRow(row, !selected);
selectedRows.value = getMultipleSelectedRows();
}
/** 处理行双击:单选直接确认,多选切换勾选 */
async function handleCellDblclick({
row,
}: {
checked: boolean;
records: MesMdWorkstationApi.Workstation[];
row?: MesMdWorkstationApi.Workstation;
row: MesMdWorkstationApi.Workstation;
}) {
if (syncingSingleSelection.value) {
if (multiple.value) {
await toggleMultipleRow(row);
return;
}
if (!multiple.value) {
const selected = checked && row ? [row] : [];
selectedRows.value = selected;
await syncSingleSelection(selected[0]);
return;
}
selectedRows.value = records;
}
/** 处理全选变化 */
function handleCheckboxAll({
records,
}: {
records: MesMdWorkstationApi.Workstation[];
}) {
if (syncingSingleSelection.value) {
return;
}
selectedRows.value = records;
selectedRows.value = [row];
await gridApi.grid.setRadioRow(row);
handleConfirm();
}
/** 回显预选工作站 */
function applyPreSelection() {
async function applyPreSelection() {
if (preSelectedIds.value.length === 0) {
return;
}
const rows = gridApi.grid.getData() as MesMdWorkstationApi.Workstation[];
for (const row of rows) {
if (row.id && preSelectedIds.value.includes(row.id)) {
gridApi.grid.setCheckboxRow(row, true);
if (!multiple.value) {
selectedRows.value = [row];
}
if (row.id === undefined || !preSelectedIds.value.includes(row.id)) {
continue;
}
if (multiple.value) {
await gridApi.grid.setCheckboxRow(row, true);
} else {
await gridApi.grid.setRadioRow(row);
selectedRows.value = [row];
return;
}
}
if (multiple.value) {
selectedRows.value = getMultipleSelectedRows();
}
}
@ -101,7 +112,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
schema: useWorkstationSelectGridFormSchema(),
},
gridOptions: {
columns: useWorkstationSelectGridColumns(),
columns: useWorkstationSelectGridColumns(true),
height: 520,
keepSource: true,
checkboxConfig: {
@ -109,6 +120,10 @@ const [Grid, gridApi] = useVbenVxeGrid({
range: true,
reserve: true,
},
radioConfig: {
highlight: true,
trigger: 'row',
},
proxyConfig: {
ajax: {
query: async ({ page }, formValues) => {
@ -131,8 +146,12 @@ const [Grid, gridApi] = useVbenVxeGrid({
},
} as VxeTableGridOptions<MesMdWorkstationApi.Workstation>,
gridEvents: {
checkboxAll: handleCheckboxAll,
checkboxChange: handleCheckboxChange,
cellDblclick: handleCellDblclick,
checkboxAll: handleCheckboxSelectChange,
checkboxChange: handleCheckboxSelectChange,
radioChange: ({ row }: { row: MesMdWorkstationApi.Workstation }) => {
handleRadioChange(row);
},
},
});
@ -140,6 +159,8 @@ const [Grid, gridApi] = useVbenVxeGrid({
async function resetQueryState() {
selectedRows.value = [];
await gridApi.grid.clearCheckboxRow();
await gridApi.grid.clearCheckboxReserve();
await gridApi.grid.clearRadioRow();
await gridApi.formApi.resetForm();
if (props.processId) {
await gridApi.formApi.setFieldValue('processId', props.processId);
@ -155,10 +176,13 @@ async function openModal(
multiple.value = options?.multiple ?? true;
preSelectedIds.value = selectedIds || [];
await nextTick();
gridApi.setGridOptions({
columns: useWorkstationSelectGridColumns(multiple.value),
});
await resetQueryState();
await gridApi.query();
await nextTick();
applyPreSelection();
await applyPreSelection();
}
/** 关闭工作站选择弹窗 */

View File

@ -44,6 +44,7 @@ const showClear = computed(
props.clearable &&
!props.disabled &&
hovering.value &&
props.modelValue !== undefined &&
props.modelValue !== null,
);

View File

@ -317,9 +317,11 @@ export function useWorkstationSelectGridFormSchema(): VbenFormSchema[] {
}
/** 工作站选择弹窗的字段 */
export function useWorkstationSelectGridColumns(): VxeTableGridOptions<MesMdWorkstationApi.Workstation>['columns'] {
export function useWorkstationSelectGridColumns(
multiple = true,
): VxeTableGridOptions<MesMdWorkstationApi.Workstation>['columns'] {
return [
{ type: 'checkbox', width: 50 },
{ type: multiple ? 'checkbox' : 'radio', width: 50 },
{
field: 'code',
title: '工作站编码',

View File

@ -37,7 +37,7 @@ const selectedRows = ref<MesProWorkOrderApi.WorkOrder[]>([]); // 已选工单列
const preSelectedIds = ref<number[]>([]); //
const typeTip = computed(() => {
if (props.type === null) {
if (props.type === undefined) {
return '';
}
return `仅展示【${getDictLabel(DICT_TYPE.MES_PRO_WORK_ORDER_TYPE, props.type)}】类型的工单`;
@ -61,6 +61,9 @@ function getMultipleSelectedRows() {
/** 处理多选勾选变化 */
function handleCheckboxSelectChange() {
if (!multiple.value) {
return;
}
selectedRows.value = getMultipleSelectedRows();
}
@ -137,8 +140,9 @@ const [Grid, gridApi] = useVbenVxeGrid({
return await getWorkOrderPage({
pageNo: page.currentPage,
pageSize: page.pageSize,
type: props.type,
...formValues,
...(props.status === undefined ? {} : { status: props.status }),
...(props.type === undefined ? {} : { type: props.type }),
});
},
},
@ -169,7 +173,7 @@ async function resetQueryState() {
await gridApi.grid.clearCheckboxReserve();
await gridApi.grid.clearRadioRow();
await gridApi.formApi.resetForm();
if (props.status !== null) {
if (props.status !== undefined) {
await gridApi.formApi.setFieldValue('status', props.status);
}
}

View File

@ -49,6 +49,7 @@ const showClear = computed(
props.clearable &&
!props.disabled &&
hovering.value &&
props.modelValue !== undefined &&
props.modelValue !== null,
);

View File

@ -19,7 +19,6 @@ const emit = defineEmits<{
const open = ref(false); //
const multiple = ref(false); //
const fixedStatus = ref<number>(); //
const syncingSingleSelection = ref(false); //
const selectedRows = ref<MesWmArrivalNoticeApi.ArrivalNotice[]>([]); //
const preSelectedIds = ref<number[]>([]); //
@ -57,10 +56,12 @@ function useSearchSchema(): VbenFormSchema[] {
}
/** 表格字段 */
function useGridColumns(): VxeTableGridOptions<MesWmArrivalNoticeApi.ArrivalNotice>['columns'] {
function useGridColumns(
multipleSelect = false,
): VxeTableGridOptions<MesWmArrivalNoticeApi.ArrivalNotice>['columns'] {
return [
{
type: 'checkbox',
type: multipleSelect ? 'checkbox' : 'radio',
width: 50,
},
{
@ -101,65 +102,77 @@ function useGridColumns(): VxeTableGridOptions<MesWmArrivalNoticeApi.ArrivalNoti
];
}
/** 单选模式下同步 VXE 勾选状态,避免跨页残留多选 */
async function syncSingleSelection(row?: MesWmArrivalNoticeApi.ArrivalNotice) {
syncingSingleSelection.value = true;
await nextTick();
await gridApi.grid.clearCheckboxRow();
if (row) {
await gridApi.grid.setCheckboxRow(row, true);
}
await nextTick();
syncingSingleSelection.value = false;
/** 获取多选记录,包含 VXE reserve 跨页记录 */
function getMultipleSelectedRows() {
const selectedMap = new Map<number, MesWmArrivalNoticeApi.ArrivalNotice>();
const records = [
...(gridApi.grid.getCheckboxReserveRecords?.() ?? []),
...(gridApi.grid.getCheckboxRecords?.() ?? []),
] as MesWmArrivalNoticeApi.ArrivalNotice[];
records.forEach((row) => {
const rowId = row.id;
if (rowId !== undefined) {
selectedMap.set(rowId, row);
}
});
return [...selectedMap.values()];
}
/** 处理勾选变化,单选模式只保留最后一条 */
async function handleCheckboxChange({
checked,
records,
/** 处理多选勾选变化 */
function handleCheckboxSelectChange() {
if (!multiple.value) {
return;
}
selectedRows.value = getMultipleSelectedRows();
}
/** 处理单选切换 */
function handleRadioChange(row: MesWmArrivalNoticeApi.ArrivalNotice) {
selectedRows.value = [row];
}
/** 多选模式下切换行勾选 */
async function toggleMultipleRow(row: MesWmArrivalNoticeApi.ArrivalNotice) {
const selected = gridApi.grid.isCheckedByCheckboxRow(row);
await gridApi.grid.setCheckboxRow(row, !selected);
selectedRows.value = getMultipleSelectedRows();
}
/** 处理行双击:单选直接确认,多选切换勾选 */
async function handleCellDblclick({
row,
}: {
checked: boolean;
records: MesWmArrivalNoticeApi.ArrivalNotice[];
row?: MesWmArrivalNoticeApi.ArrivalNotice;
row: MesWmArrivalNoticeApi.ArrivalNotice;
}) {
if (syncingSingleSelection.value) {
if (multiple.value) {
await toggleMultipleRow(row);
return;
}
if (!multiple.value) {
const selected = checked && row ? [row] : [];
selectedRows.value = selected;
await syncSingleSelection(selected[0]);
return;
}
selectedRows.value = records;
}
/** 处理全选变化 */
function handleCheckboxAll({
records,
}: {
records: MesWmArrivalNoticeApi.ArrivalNotice[];
}) {
if (syncingSingleSelection.value) {
return;
}
selectedRows.value = records;
selectedRows.value = [row];
await gridApi.grid.setRadioRow(row);
handleConfirm();
}
/** 回显预选通知单 */
function applyPreSelection() {
async function applyPreSelection() {
if (preSelectedIds.value.length === 0) {
return;
}
const rows = gridApi.grid.getData() as MesWmArrivalNoticeApi.ArrivalNotice[];
for (const row of rows) {
if (row.id && preSelectedIds.value.includes(row.id)) {
gridApi.grid.setCheckboxRow(row, true);
if (!multiple.value) {
selectedRows.value = [row];
}
if (row.id === undefined || !preSelectedIds.value.includes(row.id)) {
continue;
}
if (multiple.value) {
await gridApi.grid.setCheckboxRow(row, true);
} else {
await gridApi.grid.setRadioRow(row);
selectedRows.value = [row];
return;
}
}
if (multiple.value) {
selectedRows.value = getMultipleSelectedRows();
}
}
@ -168,7 +181,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
schema: useSearchSchema(),
},
gridOptions: {
columns: useGridColumns(),
columns: useGridColumns(false),
height: 520,
keepSource: true,
checkboxConfig: {
@ -176,6 +189,10 @@ const [Grid, gridApi] = useVbenVxeGrid({
range: true,
reserve: true,
},
radioConfig: {
highlight: true,
trigger: 'row',
},
proxyConfig: {
ajax: {
query: async ({ page }, formValues) => {
@ -198,8 +215,12 @@ const [Grid, gridApi] = useVbenVxeGrid({
},
} as VxeTableGridOptions<MesWmArrivalNoticeApi.ArrivalNotice>,
gridEvents: {
checkboxAll: handleCheckboxAll,
checkboxChange: handleCheckboxChange,
cellDblclick: handleCellDblclick,
checkboxAll: handleCheckboxSelectChange,
checkboxChange: handleCheckboxSelectChange,
radioChange: ({ row }: { row: MesWmArrivalNoticeApi.ArrivalNotice }) => {
handleRadioChange(row);
},
},
});
@ -207,6 +228,8 @@ const [Grid, gridApi] = useVbenVxeGrid({
async function resetQueryState() {
selectedRows.value = [];
await gridApi.grid.clearCheckboxRow();
await gridApi.grid.clearCheckboxReserve();
await gridApi.grid.clearRadioRow();
await gridApi.formApi.resetForm();
}
@ -220,10 +243,13 @@ async function openModal(
fixedStatus.value = options?.status;
preSelectedIds.value = selectedIds || [];
await nextTick();
gridApi.setGridOptions({
columns: useGridColumns(multiple.value),
});
await resetQueryState();
await gridApi.query();
await nextTick();
applyPreSelection();
await applyPreSelection();
}
/** 关闭通知单选择弹窗 */

View File

@ -47,6 +47,7 @@ const showClear = computed(
props.clearable &&
!props.disabled &&
hovering.value &&
props.modelValue !== undefined &&
props.modelValue !== null,
);

View File

@ -21,7 +21,6 @@ const emit = defineEmits<{
const open = ref(false); //
const multiple = ref(false); //
const fixedStatus = ref<number>(); //
const syncingSingleSelection = ref(false); //
const selectedRows = ref<MesWmSalesNoticeApi.SalesNotice[]>([]); //
const preSelectedIds = ref<number[]>([]); //
@ -84,10 +83,12 @@ function useSearchSchema(hasFixedStatus: boolean): VbenFormSchema[] {
}
/** 表格字段 */
function useGridColumns(): VxeTableGridOptions<MesWmSalesNoticeApi.SalesNotice>['columns'] {
function useGridColumns(
multipleSelect = false,
): VxeTableGridOptions<MesWmSalesNoticeApi.SalesNotice>['columns'] {
return [
{
type: 'checkbox',
type: multipleSelect ? 'checkbox' : 'radio',
width: 50,
},
{
@ -128,65 +129,77 @@ function useGridColumns(): VxeTableGridOptions<MesWmSalesNoticeApi.SalesNotice>[
];
}
/** 单选模式下同步 VXE 勾选状态,避免跨页残留多选 */
async function syncSingleSelection(row?: MesWmSalesNoticeApi.SalesNotice) {
syncingSingleSelection.value = true;
await nextTick();
await gridApi.grid.clearCheckboxRow();
if (row) {
await gridApi.grid.setCheckboxRow(row, true);
}
await nextTick();
syncingSingleSelection.value = false;
/** 获取多选记录,包含 VXE reserve 跨页记录 */
function getMultipleSelectedRows() {
const selectedMap = new Map<number, MesWmSalesNoticeApi.SalesNotice>();
const records = [
...(gridApi.grid.getCheckboxReserveRecords?.() ?? []),
...(gridApi.grid.getCheckboxRecords?.() ?? []),
] as MesWmSalesNoticeApi.SalesNotice[];
records.forEach((row) => {
const rowId = row.id;
if (rowId !== undefined) {
selectedMap.set(rowId, row);
}
});
return [...selectedMap.values()];
}
/** 处理勾选变化,单选模式只保留最后一条 */
async function handleCheckboxChange({
checked,
records,
/** 处理多选勾选变化 */
function handleCheckboxSelectChange() {
if (!multiple.value) {
return;
}
selectedRows.value = getMultipleSelectedRows();
}
/** 处理单选切换 */
function handleRadioChange(row: MesWmSalesNoticeApi.SalesNotice) {
selectedRows.value = [row];
}
/** 多选模式下切换行勾选 */
async function toggleMultipleRow(row: MesWmSalesNoticeApi.SalesNotice) {
const selected = gridApi.grid.isCheckedByCheckboxRow(row);
await gridApi.grid.setCheckboxRow(row, !selected);
selectedRows.value = getMultipleSelectedRows();
}
/** 处理行双击:单选直接确认,多选切换勾选 */
async function handleCellDblclick({
row,
}: {
checked: boolean;
records: MesWmSalesNoticeApi.SalesNotice[];
row?: MesWmSalesNoticeApi.SalesNotice;
row: MesWmSalesNoticeApi.SalesNotice;
}) {
if (syncingSingleSelection.value) {
if (multiple.value) {
await toggleMultipleRow(row);
return;
}
if (!multiple.value) {
const selected = checked && row ? [row] : [];
selectedRows.value = selected;
await syncSingleSelection(selected[0]);
return;
}
selectedRows.value = records;
}
/** 处理全选变化 */
function handleCheckboxAll({
records,
}: {
records: MesWmSalesNoticeApi.SalesNotice[];
}) {
if (syncingSingleSelection.value) {
return;
}
selectedRows.value = records;
selectedRows.value = [row];
await gridApi.grid.setRadioRow(row);
handleConfirm();
}
/** 回显预选通知单 */
function applyPreSelection() {
async function applyPreSelection() {
if (preSelectedIds.value.length === 0) {
return;
}
const rows = gridApi.grid.getData() as MesWmSalesNoticeApi.SalesNotice[];
for (const row of rows) {
if (row.id && preSelectedIds.value.includes(row.id)) {
gridApi.grid.setCheckboxRow(row, true);
if (!multiple.value) {
selectedRows.value = [row];
}
if (row.id === undefined || !preSelectedIds.value.includes(row.id)) {
continue;
}
if (multiple.value) {
await gridApi.grid.setCheckboxRow(row, true);
} else {
await gridApi.grid.setRadioRow(row);
selectedRows.value = [row];
return;
}
}
if (multiple.value) {
selectedRows.value = getMultipleSelectedRows();
}
}
@ -195,7 +208,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
schema: useSearchSchema(false),
},
gridOptions: {
columns: useGridColumns(),
columns: useGridColumns(false),
height: 520,
keepSource: true,
checkboxConfig: {
@ -203,6 +216,10 @@ const [Grid, gridApi] = useVbenVxeGrid({
range: true,
reserve: true,
},
radioConfig: {
highlight: true,
trigger: 'row',
},
proxyConfig: {
ajax: {
query: async ({ page }, formValues) => {
@ -226,8 +243,12 @@ const [Grid, gridApi] = useVbenVxeGrid({
},
} as VxeTableGridOptions<MesWmSalesNoticeApi.SalesNotice>,
gridEvents: {
checkboxAll: handleCheckboxAll,
checkboxChange: handleCheckboxChange,
cellDblclick: handleCellDblclick,
checkboxAll: handleCheckboxSelectChange,
checkboxChange: handleCheckboxSelectChange,
radioChange: ({ row }: { row: MesWmSalesNoticeApi.SalesNotice }) => {
handleRadioChange(row);
},
},
});
@ -235,6 +256,8 @@ const [Grid, gridApi] = useVbenVxeGrid({
async function resetQueryState() {
selectedRows.value = [];
await gridApi.grid.clearCheckboxRow();
await gridApi.grid.clearCheckboxReserve();
await gridApi.grid.clearRadioRow();
await gridApi.formApi.resetForm();
}
@ -249,13 +272,16 @@ async function openModal(
preSelectedIds.value = selectedIds || [];
//
gridApi.formApi.setState({
schema: useSearchSchema(fixedStatus.value !== null),
schema: useSearchSchema(fixedStatus.value !== undefined),
});
await nextTick();
gridApi.setGridOptions({
columns: useGridColumns(multiple.value),
});
await resetQueryState();
await gridApi.query();
await nextTick();
applyPreSelection();
await applyPreSelection();
}
/** 关闭通知单选择弹窗 */

View File

@ -47,6 +47,7 @@ const showClear = computed(
props.clearable &&
!props.disabled &&
hovering.value &&
props.modelValue !== undefined &&
props.modelValue !== null,
);