docs(mes): 登记 MES-B033~B036 修复并更新 review 索引

- INDEX.md: R014、R026、R031、R039 转 fixed,分别关联 MES-B033~B036
- bug_done.md: 追加 B033(client 销售记录详情入口)、B034(salesnotice
  选择弹窗筛选)、B035(高基数选择器恢复分页弹窗)、B036(RQC 保存后
  留在弹窗编辑子表)完整修复记录
- bug_rejected.md: 同步前序 B029 归档调整

剩余 open: R006、R010;disputed: R008、R009。
pull/351/MERGE
YunaiV 2026-05-31 13:17:21 +08:00
parent a188c8245d
commit 2fc7390091
24 changed files with 1219 additions and 208 deletions

View File

@ -1 +1,2 @@
export { default as DvCheckPlanSelectDialog } from './select-dialog.vue';
export { default as DvCheckPlanSelect } from './select.vue';

View File

@ -1,15 +1,19 @@
<script lang="ts" setup>
import type { SelectValue } from 'ant-design-vue/es/select';
import type { MesDvCheckPlanApi } from '#/api/mes/dv/checkplan';
import { onMounted, ref, watch } from 'vue';
import { computed, ref, useAttrs, watch } from 'vue';
import { Select } from 'ant-design-vue';
import { DICT_TYPE } from '@vben/constants';
import { IconifyIcon } from '@vben/icons';
import { getCheckPlanPage } from '#/api/mes/dv/checkplan';
import { Input, Tooltip } from 'ant-design-vue';
defineOptions({ name: 'DvCheckPlanSelect' });
import { getCheckPlan } from '#/api/mes/dv/checkplan';
import { DictTag } from '#/components/dict-tag';
import DvCheckPlanSelectDialog from './select-dialog.vue';
defineOptions({ name: 'DvCheckPlanSelect', inheritAttrs: false });
const props = withDefaults(
defineProps<{
@ -24,51 +28,125 @@ const props = withDefaults(
allowClear: true,
disabled: false,
modelValue: undefined,
placeholder: '请选择计划',
placeholder: '请选择保养方案',
status: undefined,
type: undefined,
},
);
const emit = defineEmits<{
change: [row?: MesDvCheckPlanApi.CheckPlan];
'update:modelValue': [value?: number];
change: [item: MesDvCheckPlanApi.CheckPlan | undefined];
'update:modelValue': [value: number | undefined];
}>();
const list = ref<MesDvCheckPlanApi.CheckPlan[]>([]); //
const attrs = useAttrs(); //
const dialogRef = ref<InstanceType<typeof DvCheckPlanSelectDialog>>(); //
const hovering = ref(false); //
const selectedItem = ref<MesDvCheckPlanApi.CheckPlan>(); //
/** 加载点检计划列表 */
async function getList() {
const data = await getCheckPlanPage({
pageNo: 1,
pageSize: 100,
const displayLabel = computed(() => selectedItem.value?.name ?? ''); //
const showClear = computed(
() =>
props.allowClear &&
!props.disabled &&
hovering.value &&
props.modelValue != null,
);
/** 根据方案编号回显选择器 */
async function resolveItemById(id: number | undefined) {
if (id == null) {
selectedItem.value = undefined;
return;
}
if (selectedItem.value?.id === id) {
return;
}
selectedItem.value = await getCheckPlan(id);
}
watch(
() => props.modelValue,
(value) => {
resolveItemById(value);
},
{ immediate: true },
);
/** 清空已选方案 */
function clearSelected() {
selectedItem.value = undefined;
emit('update:modelValue', undefined);
emit('change', undefined);
}
/** 打开方案选择弹窗 */
function handleClick(event: MouseEvent) {
if (props.disabled) {
return;
}
const target = event.target as HTMLElement;
if (showClear.value && target.closest('.ant-input-suffix')) {
event.stopPropagation();
clearSelected();
return;
}
const selectedIds = props.modelValue == null ? [] : [props.modelValue];
dialogRef.value?.open(selectedIds, {
multiple: false,
status: props.status,
type: props.type,
});
list.value = data.list || [];
}
/** 处理点检计划选择变化 */
function handleChange(value: SelectValue) {
const planId = typeof value === 'number' ? value : undefined;
emit('update:modelValue', planId);
emit('change', list.value.find((item) => item.id === planId));
/** 回填选中的方案 */
function handleSelected(rows: MesDvCheckPlanApi.CheckPlan[]) {
const item = rows[0];
if (!item) {
return;
}
selectedItem.value = item;
emit('update:modelValue', item.id);
emit('change', item);
}
watch(() => [props.status, props.type], getList);
onMounted(getList);
</script>
<template>
<Select
:allow-clear="allowClear"
:disabled="disabled"
:field-names="{ label: 'name', value: 'id' }"
:options="list"
:placeholder="placeholder"
:value="modelValue"
<div
v-bind="attrs"
class="w-full"
option-filter-prop="name"
show-search
@change="handleChange"
/>
:class="disabled ? 'cursor-not-allowed' : 'cursor-pointer'"
@click="handleClick"
@mouseenter="hovering = true"
@mouseleave="hovering = false"
>
<Tooltip :mouse-enter-delay="0.5" :open="selectedItem ? undefined : false">
<template #title>
<div v-if="selectedItem" class="leading-6">
<div>编码{{ selectedItem.code || '-' }}</div>
<div>名称{{ selectedItem.name || '-' }}</div>
<div class="flex items-center">
频度{{ selectedItem.cycleCount ?? '-' }}
<DictTag
class="ml-1"
:type="DICT_TYPE.MES_DV_CYCLE_TYPE"
:value="selectedItem.cycleType"
/>
</div>
</div>
</template>
<Input
:disabled="disabled"
:placeholder="placeholder"
:value="displayLabel"
readonly
>
<template #suffix>
<IconifyIcon
class="size-4"
:icon="showClear ? 'lucide:circle-x' : 'lucide:search'"
/>
</template>
</Input>
</Tooltip>
</div>
<DvCheckPlanSelectDialog ref="dialogRef" @selected="handleSelected" />
</template>

View File

@ -245,3 +245,68 @@ export function useGridColumns(): VxeTableGridOptions<MesDvCheckPlanApi.CheckPla
},
];
}
/** 点检方案选择弹窗的搜索表单 */
export function useCheckPlanSelectGridFormSchema(): VbenFormSchema[] {
return [
{
fieldName: 'code',
label: '计划编号',
component: 'Input',
componentProps: {
allowClear: true,
placeholder: '请输入计划编号',
},
},
{
fieldName: 'name',
label: '计划名称',
component: 'Input',
componentProps: {
allowClear: true,
placeholder: '请输入计划名称',
},
},
];
}
/** 点检方案选择弹窗的字段 */
export function useCheckPlanSelectGridColumns(
multiple = false,
): VxeTableGridOptions<MesDvCheckPlanApi.CheckPlan>['columns'] {
return [
{ type: multiple ? 'checkbox' : 'radio', width: 50 },
{ field: 'code', title: '计划编码', minWidth: 180 },
{ field: 'name', title: '计划名称', minWidth: 150 },
{
field: 'type',
title: '计划类型',
width: 120,
cellRender: {
name: 'CellDict',
props: { type: DICT_TYPE.MES_DV_SUBJECT_TYPE },
},
},
{ field: 'startDate', title: '开始日期', width: 120, formatter: 'formatDate' },
{ field: 'endDate', title: '结束日期', width: 120, formatter: 'formatDate' },
{ field: 'cycleCount', title: '频率', width: 100 },
{
field: 'cycleType',
title: '周期类型',
width: 120,
cellRender: {
name: 'CellDict',
props: { type: DICT_TYPE.MES_DV_CYCLE_TYPE },
},
},
{
field: 'status',
title: '状态',
width: 100,
cellRender: {
name: 'CellDict',
props: { type: DICT_TYPE.MES_DV_CHECK_PLAN_STATUS },
},
},
];
}

View File

@ -1 +1,2 @@
export { default as DvMachinerySelectDialog } from './select-dialog.vue';
export { default as DvMachinerySelect } from './select.vue';

View File

@ -1,17 +1,19 @@
<script lang="ts" setup>
import type { SelectValue } from 'ant-design-vue/es/select';
import type { MesDvMachineryApi } from '#/api/mes/dv/machinery';
import { onMounted, ref } from 'vue';
import { computed, ref, useAttrs, watch } from 'vue';
import { Select } from 'ant-design-vue';
import { IconifyIcon } from '@vben/icons';
import { getMachinerySimpleList } from '#/api/mes/dv/machinery';
import { Input, Tooltip } from 'ant-design-vue';
defineOptions({ name: 'DvMachinerySelect' });
import { getMachinery } from '#/api/mes/dv/machinery';
withDefaults(
import DvMachinerySelectDialog from './select-dialog.vue';
defineOptions({ name: 'DvMachinerySelect', inheritAttrs: false });
const props = withDefaults(
defineProps<{
allowClear?: boolean;
disabled?: boolean;
@ -26,37 +28,111 @@ withDefaults(
},
);
const emit = defineEmits<{
change: [row?: MesDvMachineryApi.Machinery];
'update:modelValue': [value?: number];
change: [item: MesDvMachineryApi.Machinery | undefined];
'update:modelValue': [value: number | undefined];
}>();
const list = ref<MesDvMachineryApi.Machinery[]>([]); //
const attrs = useAttrs(); //
const dialogRef = ref<InstanceType<typeof DvMachinerySelectDialog>>(); //
const hovering = ref(false); //
const selectedItem = ref<MesDvMachineryApi.Machinery>(); //
/** 加载设备列表 */
async function getList() {
list.value = await getMachinerySimpleList();
const displayLabel = computed(() => selectedItem.value?.name ?? ''); //
const showClear = computed(
() =>
props.allowClear &&
!props.disabled &&
hovering.value &&
props.modelValue != null,
);
/** 根据设备编号回显选择器 */
async function resolveItemById(id: number | undefined) {
if (id == null) {
selectedItem.value = undefined;
return;
}
if (selectedItem.value?.id === id) {
return;
}
selectedItem.value = await getMachinery(id);
}
/** 处理设备选择变化 */
function handleChange(value: SelectValue) {
const machineryId = typeof value === 'number' ? value : undefined;
emit('update:modelValue', machineryId);
emit('change', list.value.find((item) => item.id === machineryId));
watch(
() => props.modelValue,
(value) => {
resolveItemById(value);
},
{ immediate: true },
);
/** 清空已选设备 */
function clearSelected() {
selectedItem.value = undefined;
emit('update:modelValue', undefined);
emit('change', undefined);
}
onMounted(getList);
/** 打开设备选择弹窗 */
function handleClick(event: MouseEvent) {
if (props.disabled) {
return;
}
const target = event.target as HTMLElement;
if (showClear.value && target.closest('.ant-input-suffix')) {
event.stopPropagation();
clearSelected();
return;
}
const selectedIds = props.modelValue == null ? [] : [props.modelValue];
dialogRef.value?.open(selectedIds, { multiple: false });
}
/** 回填选中的设备 */
function handleSelected(rows: MesDvMachineryApi.Machinery[]) {
const item = rows[0];
if (!item) {
return;
}
selectedItem.value = item;
emit('update:modelValue', item.id);
emit('change', item);
}
</script>
<template>
<Select
:allow-clear="allowClear"
:disabled="disabled"
:field-names="{ label: 'name', value: 'id' }"
:options="list"
:placeholder="placeholder"
:value="modelValue"
<div
v-bind="attrs"
class="w-full"
option-filter-prop="name"
show-search
@change="handleChange"
/>
:class="disabled ? 'cursor-not-allowed' : 'cursor-pointer'"
@click="handleClick"
@mouseenter="hovering = true"
@mouseleave="hovering = false"
>
<Tooltip :mouse-enter-delay="0.5" :open="selectedItem ? undefined : false">
<template #title>
<div v-if="selectedItem" class="leading-6">
<div>设备编码{{ selectedItem.code || '-' }}</div>
<div>设备名称{{ selectedItem.name || '-' }}</div>
<div v-if="selectedItem.brand">{{ selectedItem.brand }}</div>
<div v-if="selectedItem.specification">
规格型号{{ selectedItem.specification }}
</div>
</div>
</template>
<Input
:disabled="disabled"
:placeholder="placeholder"
:value="displayLabel"
readonly
>
<template #suffix>
<IconifyIcon
class="size-4"
:icon="showClear ? 'lucide:circle-x' : 'lucide:search'"
/>
</template>
</Input>
</Tooltip>
</div>
<DvMachinerySelectDialog ref="dialogRef" @selected="handleSelected" />
</template>

View File

@ -276,3 +276,65 @@ export function useImportFormSchema(): VbenFormSchema[] {
},
];
}
/** 设备选择弹窗的搜索表单 */
export function useMachinerySelectGridFormSchema(): VbenFormSchema[] {
return [
{
fieldName: 'code',
label: '设备编码',
component: 'Input',
componentProps: {
allowClear: true,
placeholder: '请输入设备编码',
},
},
{
fieldName: 'name',
label: '设备名称',
component: 'Input',
componentProps: {
allowClear: true,
placeholder: '请输入设备名称',
},
},
{
fieldName: 'workshopId',
label: '所属车间',
component: markRaw(MdWorkshopSelect),
componentProps: {
allowClear: true,
placeholder: '请选择所属车间',
},
},
];
}
/** 设备选择弹窗的字段 */
export function useMachinerySelectGridColumns(
multiple = false,
): VxeTableGridOptions<MesDvMachineryApi.Machinery>['columns'] {
return [
{ type: multiple ? 'checkbox' : 'radio', width: 50 },
{ field: 'code', title: '设备编码', width: 120 },
{ field: 'name', title: '设备名称', minWidth: 120 },
{ field: 'brand', title: '品牌', minWidth: 120 },
{ field: 'specification', title: '规格型号', minWidth: 120 },
{ field: 'workshopName', title: '所属车间', width: 120 },
{
field: 'status',
title: '设备状态',
width: 100,
cellRender: {
name: 'CellDict',
props: { type: DICT_TYPE.MES_DV_MACHINERY_STATUS },
},
},
{
field: 'createTime',
title: '创建时间',
width: 160,
formatter: 'formatDateTime',
},
];
}

View File

@ -2,15 +2,31 @@
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { MesWmProductSalesApi } from '#/api/mes/wm/productsales';
import { useVbenModal } from '@vben/common-ui';
import { DICT_TYPE } from '@vben/constants';
import { Button } from 'ant-design-vue';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { getProductSalesPage } from '#/api/mes/wm/productsales';
import ProductSalesForm from '#/views/mes/wm/productsales/modules/form.vue';
const props = defineProps<{
clientId: number;
}>();
const [DetailModal, detailModalApi] = useVbenModal({
connectedComponent: ProductSalesForm,
destroyOnClose: true,
});
/** 查看销售出库单详情 */
function handleViewSales(row: MesWmProductSalesApi.ProductSales) {
if (row.id) {
detailModalApi.setData({ formType: 'detail', id: row.id }).open();
}
}
const [Grid] = useVbenVxeGrid({
gridOptions: {
columns: [
@ -18,6 +34,7 @@ const [Grid] = useVbenVxeGrid({
field: 'code',
title: '出库单编号',
minWidth: 160,
slots: { default: 'code' },
},
{
field: 'name',
@ -70,5 +87,12 @@ const [Grid] = useVbenVxeGrid({
</script>
<template>
<Grid table-title="" />
<DetailModal />
<Grid table-title="">
<template #code="{ row }">
<Button type="link" @click="handleViewSales(row)">
{{ row.code }}
</Button>
</template>
</Grid>
</template>

View File

@ -136,9 +136,7 @@ const [Modal, modalApi] = useVbenModal({
if (!ok) {
return;
}
//
message.success($t('ui.actionMessage.operationSuccess'));
await modalApi.close();
emit('success');
} finally {
modalApi.unlock();
@ -160,7 +158,10 @@ const [Modal, modalApi] = useVbenModal({
formType.value = data.formType;
formApi.setState({ schema: useFormSchema(formType.value, formApi) });
formApi.setDisabled(formType.value === 'detail');
modalApi.setState({ showConfirmButton: formType.value !== 'detail' });
modalApi.setState({
confirmText: formType.value === 'detail' ? undefined : '保存',
showConfirmButton: formType.value !== 'detail',
});
if (data?.id) {
modalApi.lock();
try {

View File

@ -1 +1,2 @@
export { default as TmToolSelectDialog } from './select-dialog.vue';
export { default as TmToolSelect } from './select.vue';

View File

@ -1,55 +1,141 @@
<script lang="ts" setup>
import type { SelectValue } from 'ant-design-vue/es/select';
import type { MesTmToolApi } from '#/api/mes/tm/tool';
import { onMounted, ref } from 'vue';
import { computed, ref, useAttrs, watch } from 'vue';
import { Select } from 'ant-design-vue';
import { IconifyIcon } from '@vben/icons';
import { getToolSimpleList } from '#/api/mes/tm/tool';
import { Input, Tooltip } from 'ant-design-vue';
withDefaults(
import { getTool } from '#/api/mes/tm/tool';
import TmToolSelectDialog from './select-dialog.vue';
defineOptions({ name: 'TmToolSelect', inheritAttrs: false });
const props = withDefaults(
defineProps<{
allowClear?: boolean;
disabled?: boolean;
modelValue?: number;
placeholder?: string;
}>(),
{ allowClear: true, disabled: false, modelValue: undefined, placeholder: '请选择工具' },
{
allowClear: true,
disabled: false,
modelValue: undefined,
placeholder: '请选择工具',
},
);
const emit = defineEmits<{
change: [row?: MesTmToolApi.Tool];
'update:modelValue': [value?: number];
change: [item: MesTmToolApi.Tool | undefined];
'update:modelValue': [value: number | undefined];
}>();
const list = ref<MesTmToolApi.Tool[]>([]); //
const attrs = useAttrs(); //
const dialogRef = ref<InstanceType<typeof TmToolSelectDialog>>(); //
const hovering = ref(false); //
const selectedItem = ref<MesTmToolApi.Tool>(); //
/** 加载工具列表 */
async function getList() {
list.value = await getToolSimpleList();
const displayLabel = computed(() => selectedItem.value?.name ?? ''); //
const showClear = computed(
() =>
props.allowClear &&
!props.disabled &&
hovering.value &&
props.modelValue != null,
);
/** 根据工具编号回显选择器 */
async function resolveItemById(id: number | undefined) {
if (id == null) {
selectedItem.value = undefined;
return;
}
if (selectedItem.value?.id === id) {
return;
}
selectedItem.value = await getTool(id);
}
/** 处理工具选择变化 */
function handleChange(value: SelectValue) {
const toolId = typeof value === 'number' ? value : undefined;
emit('update:modelValue', toolId);
emit('change', list.value.find((item) => item.id === toolId));
watch(
() => props.modelValue,
(value) => {
resolveItemById(value);
},
{ immediate: true },
);
/** 清空已选工具 */
function clearSelected() {
selectedItem.value = undefined;
emit('update:modelValue', undefined);
emit('change', undefined);
}
onMounted(getList);
/** 打开工具选择弹窗 */
function handleClick(event: MouseEvent) {
if (props.disabled) {
return;
}
const target = event.target as HTMLElement;
if (showClear.value && target.closest('.ant-input-suffix')) {
event.stopPropagation();
clearSelected();
return;
}
const selectedIds = props.modelValue == null ? [] : [props.modelValue];
dialogRef.value?.open(selectedIds, { multiple: false });
}
/** 回填选中的工具 */
function handleSelected(rows: MesTmToolApi.Tool[]) {
const item = rows[0];
if (!item) {
return;
}
selectedItem.value = item;
emit('update:modelValue', item.id);
emit('change', item);
}
</script>
<template>
<Select
:allow-clear="allowClear"
:disabled="disabled"
:field-names="{ label: 'name', value: 'id' }"
:options="list"
:placeholder="placeholder"
:value="modelValue"
<div
v-bind="attrs"
class="w-full"
option-filter-prop="name"
show-search
@change="handleChange"
/>
:class="disabled ? 'cursor-not-allowed' : 'cursor-pointer'"
@click="handleClick"
@mouseenter="hovering = true"
@mouseleave="hovering = false"
>
<Tooltip :mouse-enter-delay="0.5" :open="selectedItem ? undefined : false">
<template #title>
<div v-if="selectedItem" class="leading-6">
<div>工具编码{{ selectedItem.code || '-' }}</div>
<div>工具名称{{ selectedItem.name || '-' }}</div>
<div v-if="selectedItem.brand">{{ selectedItem.brand }}</div>
<div v-if="selectedItem.specification">
型号规格{{ selectedItem.specification }}
</div>
<div v-if="selectedItem.toolTypeName">
工具类型{{ selectedItem.toolTypeName }}
</div>
</div>
</template>
<Input
:disabled="disabled"
:placeholder="placeholder"
:value="displayLabel"
readonly
>
<template #suffix>
<IconifyIcon
class="size-4"
:icon="showClear ? 'lucide:circle-x' : 'lucide:search'"
/>
</template>
</Input>
</Tooltip>
</div>
<TmToolSelectDialog ref="dialogRef" @selected="handleSelected" />
</template>

View File

@ -325,3 +325,85 @@ export function useGridColumns(): VxeTableGridOptions<MesTmToolApi.Tool>['column
},
];
}
/** 工具选择弹窗的搜索表单 */
export function useToolSelectGridFormSchema(): VbenFormSchema[] {
return [
{
fieldName: 'code',
label: '工具编码',
component: 'Input',
componentProps: {
allowClear: true,
placeholder: '请输入工具编码',
},
},
{
fieldName: 'name',
label: '工具名称',
component: 'Input',
componentProps: {
allowClear: true,
placeholder: '请输入工具名称',
},
},
{
fieldName: 'toolTypeId',
label: '工具类型',
component: markRaw(TmToolTypeSelect),
componentProps: {
placeholder: '请选择工具类型',
},
},
{
fieldName: 'brand',
label: '品牌',
component: 'Input',
componentProps: {
allowClear: true,
placeholder: '请输入品牌',
},
},
{
fieldName: 'status',
label: '状态',
component: 'Select',
componentProps: {
allowClear: true,
options: getDictOptions(DICT_TYPE.MES_TM_TOOL_STATUS, 'number'),
placeholder: '请选择状态',
},
},
];
}
/** 工具选择弹窗的字段 */
export function useToolSelectGridColumns(
multiple = false,
): VxeTableGridOptions<MesTmToolApi.Tool>['columns'] {
return [
{ type: multiple ? 'checkbox' : 'radio', width: 50 },
{ field: 'code', title: '工具编码', width: 120 },
{ field: 'name', title: '工具名称', minWidth: 120 },
{ field: 'brand', title: '品牌', minWidth: 100 },
{ field: 'specification', title: '型号规格', minWidth: 100 },
{ field: 'toolTypeName', title: '工具类型', width: 120 },
{ field: 'quantity', title: '库存数量', width: 100 },
{ field: 'availableQuantity', title: '可用数量', width: 100 },
{
field: 'status',
title: '状态',
width: 100,
cellRender: {
name: 'CellDict',
props: { type: DICT_TYPE.MES_TM_TOOL_STATUS },
},
},
{
field: 'createTime',
title: '创建时间',
width: 180,
formatter: 'formatDateTime',
},
];
}

View File

@ -3,14 +3,16 @@ import type { VbenFormSchema } from '#/adapter/form';
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { MesWmSalesNoticeApi } from '#/api/mes/wm/salesnotice';
import { nextTick, ref } from 'vue';
import { markRaw, nextTick, ref } from 'vue';
import { DICT_TYPE } from '@vben/constants';
import { getDictOptions } from '@vben/hooks';
import { message, Modal } from 'ant-design-vue';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { getSalesNoticePage } from '#/api/mes/wm/salesnotice';
import { MdClientSelect } from '#/views/mes/md/client/components';
const emit = defineEmits<{
selected: [rows: MesWmSalesNoticeApi.SalesNotice[]];
@ -23,8 +25,8 @@ const syncingSingleSelection = ref(false); // 是否同步单选勾选状态
const selectedRows = ref<MesWmSalesNoticeApi.SalesNotice[]>([]); //
const preSelectedIds = ref<number[]>([]); //
/** 搜索表单 */
function useSearchSchema(): VbenFormSchema[] {
/** 搜索表单:未固定状态时展示状态下拉,固定状态时隐藏 */
function useSearchSchema(hasFixedStatus: boolean): VbenFormSchema[] {
return [
{
fieldName: 'code',
@ -53,6 +55,31 @@ function useSearchSchema(): VbenFormSchema[] {
placeholder: '请输入销售订单编号',
},
},
{
fieldName: 'clientId',
label: '客户',
component: markRaw(MdClientSelect),
componentProps: {
placeholder: '请选择客户',
},
},
...(hasFixedStatus
? []
: [
{
fieldName: 'status',
label: '单据状态',
component: 'Select',
componentProps: {
allowClear: true,
options: getDictOptions(
DICT_TYPE.MES_WM_SALES_NOTICE_STATUS,
'number',
),
placeholder: '请选择单据状态',
},
} as VbenFormSchema,
]),
];
}
@ -165,7 +192,7 @@ function applyPreSelection() {
const [Grid, gridApi] = useVbenVxeGrid({
formOptions: {
schema: useSearchSchema(),
schema: useSearchSchema(false),
},
gridOptions: {
columns: useGridColumns(),
@ -182,8 +209,9 @@ const [Grid, gridApi] = useVbenVxeGrid({
return await getSalesNoticePage({
pageNo: page.currentPage,
pageSize: page.pageSize,
status: fixedStatus.value,
...formValues,
//
status: fixedStatus.value ?? formValues.status,
});
},
},
@ -219,6 +247,10 @@ async function openModal(
multiple.value = options?.multiple ?? false;
fixedStatus.value = options?.status;
preSelectedIds.value = selectedIds || [];
//
gridApi.formApi.setState({
schema: useSearchSchema(fixedStatus.value != null),
});
await nextTick();
await resetQueryState();
await gridApi.query();

View File

@ -1 +1,2 @@
export { default as DvCheckPlanSelectDialog } from './select-dialog.vue';
export { default as DvCheckPlanSelect } from './select.vue';

View File

@ -1,13 +1,19 @@
<script lang="ts" setup>
import type { MesDvCheckPlanApi } from '#/api/mes/dv/checkplan';
import { onMounted, ref, watch } from 'vue';
import { computed, ref, useAttrs, watch } from 'vue';
import { ElOption, ElSelect } from 'element-plus';
import { DICT_TYPE } from '@vben/constants';
import { CircleX, Search } from '@vben/icons';
import { getCheckPlanPage } from '#/api/mes/dv/checkplan';
import { ElInput, ElTooltip } from 'element-plus';
defineOptions({ name: 'DvCheckPlanSelect' });
import { getCheckPlan } from '#/api/mes/dv/checkplan';
import { DictTag } from '#/components/dict-tag';
import DvCheckPlanSelectDialog from './select-dialog.vue';
defineOptions({ name: 'DvCheckPlanSelect', inheritAttrs: false });
const props = withDefaults(
defineProps<{
@ -22,55 +28,123 @@ const props = withDefaults(
clearable: true,
disabled: false,
modelValue: undefined,
placeholder: '请选择计划',
placeholder: '请选择保养方案',
status: undefined,
type: undefined,
},
);
const emit = defineEmits<{
change: [row?: MesDvCheckPlanApi.CheckPlan];
'update:modelValue': [value?: number];
change: [item: MesDvCheckPlanApi.CheckPlan | undefined];
'update:modelValue': [value: number | undefined];
}>();
const list = ref<MesDvCheckPlanApi.CheckPlan[]>([]); //
const attrs = useAttrs(); //
const dialogRef = ref<InstanceType<typeof DvCheckPlanSelectDialog>>(); //
const hovering = ref(false); //
const selectedItem = ref<MesDvCheckPlanApi.CheckPlan>(); //
/** 加载点检计划列表 */
async function getList() {
const data = await getCheckPlanPage({
pageNo: 1,
pageSize: 100,
const displayLabel = computed(() => selectedItem.value?.name ?? ''); //
const showClear = computed(
() =>
props.clearable &&
!props.disabled &&
hovering.value &&
props.modelValue != null,
);
/** 根据方案编号回显选择器 */
async function resolveItemById(id: number | undefined) {
if (id == null) {
selectedItem.value = undefined;
return;
}
if (selectedItem.value?.id === id) {
return;
}
selectedItem.value = await getCheckPlan(id);
}
watch(
() => props.modelValue,
(value) => {
resolveItemById(value);
},
{ immediate: true },
);
/** 清空已选方案 */
function clearSelected() {
selectedItem.value = undefined;
emit('update:modelValue', undefined);
emit('change', undefined);
}
/** 打开方案选择弹窗 */
function handleClick(event: MouseEvent) {
if (props.disabled) {
return;
}
const target = event.target as HTMLElement;
if (showClear.value && target.closest('.el-input__suffix')) {
event.stopPropagation();
clearSelected();
return;
}
const selectedIds = props.modelValue == null ? [] : [props.modelValue];
dialogRef.value?.open(selectedIds, {
multiple: false,
status: props.status,
type: props.type,
});
list.value = data.list || [];
}
/** 处理点检计划选择变化 */
function handleChange(value: number | string | undefined) {
const planId = typeof value === 'number' ? value : undefined;
emit('update:modelValue', planId);
emit('change', list.value.find((item) => item.id === planId));
/** 回填选中的方案 */
function handleSelected(rows: MesDvCheckPlanApi.CheckPlan[]) {
const item = rows[0];
if (!item) {
return;
}
selectedItem.value = item;
emit('update:modelValue', item.id);
emit('change', item);
}
watch(() => [props.status, props.type], getList);
onMounted(getList);
</script>
<template>
<ElSelect
:clearable="clearable"
:disabled="disabled"
:model-value="modelValue"
:placeholder="placeholder"
<div
v-bind="attrs"
class="w-full"
filterable
@change="handleChange"
:class="disabled ? 'cursor-not-allowed' : 'cursor-pointer'"
@click="handleClick"
@mouseenter="hovering = true"
@mouseleave="hovering = false"
>
<ElOption
v-for="item in list"
:key="item.id"
:label="item.name"
:value="item.id!"
/>
</ElSelect>
<ElTooltip :disabled="!selectedItem" placement="top" :show-after="500">
<template #content>
<div v-if="selectedItem" class="leading-6">
<div>编码{{ selectedItem.code || '-' }}</div>
<div>名称{{ selectedItem.name || '-' }}</div>
<div class="flex items-center">
频度{{ selectedItem.cycleCount ?? '-' }}
<DictTag
class="ml-1"
:type="DICT_TYPE.MES_DV_CYCLE_TYPE"
:value="selectedItem.cycleType"
/>
</div>
</div>
</template>
<ElInput
:disabled="disabled"
:model-value="displayLabel"
:placeholder="placeholder"
readonly
>
<template #suffix>
<CircleX v-if="showClear" class="size-4" />
<Search v-else class="size-4" />
</template>
</ElInput>
</ElTooltip>
</div>
<DvCheckPlanSelectDialog ref="dialogRef" @selected="handleSelected" />
</template>

View File

@ -245,3 +245,68 @@ export function useGridColumns(): VxeTableGridOptions<MesDvCheckPlanApi.CheckPla
},
];
}
/** 点检方案选择弹窗的搜索表单 */
export function useCheckPlanSelectGridFormSchema(): VbenFormSchema[] {
return [
{
fieldName: 'code',
label: '计划编号',
component: 'Input',
componentProps: {
clearable: true,
placeholder: '请输入计划编号',
},
},
{
fieldName: 'name',
label: '计划名称',
component: 'Input',
componentProps: {
clearable: true,
placeholder: '请输入计划名称',
},
},
];
}
/** 点检方案选择弹窗的字段 */
export function useCheckPlanSelectGridColumns(
multiple = false,
): VxeTableGridOptions<MesDvCheckPlanApi.CheckPlan>['columns'] {
return [
{ type: multiple ? 'checkbox' : 'radio', width: 50 },
{ field: 'code', title: '计划编码', minWidth: 180 },
{ field: 'name', title: '计划名称', minWidth: 150 },
{
field: 'type',
title: '计划类型',
width: 120,
cellRender: {
name: 'CellDict',
props: { type: DICT_TYPE.MES_DV_SUBJECT_TYPE },
},
},
{ field: 'startDate', title: '开始日期', width: 120, formatter: 'formatDate' },
{ field: 'endDate', title: '结束日期', width: 120, formatter: 'formatDate' },
{ field: 'cycleCount', title: '频率', width: 100 },
{
field: 'cycleType',
title: '周期类型',
width: 120,
cellRender: {
name: 'CellDict',
props: { type: DICT_TYPE.MES_DV_CYCLE_TYPE },
},
},
{
field: 'status',
title: '状态',
width: 100,
cellRender: {
name: 'CellDict',
props: { type: DICT_TYPE.MES_DV_CHECK_PLAN_STATUS },
},
},
];
}

View File

@ -1 +1,2 @@
export { default as DvMachinerySelectDialog } from './select-dialog.vue';
export { default as DvMachinerySelect } from './select.vue';

View File

@ -1,15 +1,19 @@
<script lang="ts" setup>
import type { MesDvMachineryApi } from '#/api/mes/dv/machinery';
import { onMounted, ref } from 'vue';
import { computed, ref, useAttrs, watch } from 'vue';
import { ElOption, ElSelect } from 'element-plus';
import { CircleX, Search } from '@vben/icons';
import { getMachinerySimpleList } from '#/api/mes/dv/machinery';
import { ElInput, ElTooltip } from 'element-plus';
defineOptions({ name: 'DvMachinerySelect' });
import { getMachinery } from '#/api/mes/dv/machinery';
withDefaults(
import DvMachinerySelectDialog from './select-dialog.vue';
defineOptions({ name: 'DvMachinerySelect', inheritAttrs: false });
const props = withDefaults(
defineProps<{
clearable?: boolean;
disabled?: boolean;
@ -24,41 +28,109 @@ withDefaults(
},
);
const emit = defineEmits<{
change: [row?: MesDvMachineryApi.Machinery];
'update:modelValue': [value?: number];
change: [item: MesDvMachineryApi.Machinery | undefined];
'update:modelValue': [value: number | undefined];
}>();
const list = ref<MesDvMachineryApi.Machinery[]>([]); //
const attrs = useAttrs(); //
const dialogRef = ref<InstanceType<typeof DvMachinerySelectDialog>>(); //
const hovering = ref(false); //
const selectedItem = ref<MesDvMachineryApi.Machinery>(); //
/** 加载设备列表 */
async function getList() {
list.value = await getMachinerySimpleList();
const displayLabel = computed(() => selectedItem.value?.name ?? ''); //
const showClear = computed(
() =>
props.clearable &&
!props.disabled &&
hovering.value &&
props.modelValue != null,
);
/** 根据设备编号回显选择器 */
async function resolveItemById(id: number | undefined) {
if (id == null) {
selectedItem.value = undefined;
return;
}
if (selectedItem.value?.id === id) {
return;
}
selectedItem.value = await getMachinery(id);
}
/** 处理设备选择变化 */
function handleChange(value: number | string | undefined) {
const machineryId = typeof value === 'number' ? value : undefined;
emit('update:modelValue', machineryId);
emit('change', list.value.find((item) => item.id === machineryId));
watch(
() => props.modelValue,
(value) => {
resolveItemById(value);
},
{ immediate: true },
);
/** 清空已选设备 */
function clearSelected() {
selectedItem.value = undefined;
emit('update:modelValue', undefined);
emit('change', undefined);
}
onMounted(getList);
/** 打开设备选择弹窗 */
function handleClick(event: MouseEvent) {
if (props.disabled) {
return;
}
const target = event.target as HTMLElement;
if (showClear.value && target.closest('.el-input__suffix')) {
event.stopPropagation();
clearSelected();
return;
}
const selectedIds = props.modelValue == null ? [] : [props.modelValue];
dialogRef.value?.open(selectedIds, { multiple: false });
}
/** 回填选中的设备 */
function handleSelected(rows: MesDvMachineryApi.Machinery[]) {
const item = rows[0];
if (!item) {
return;
}
selectedItem.value = item;
emit('update:modelValue', item.id);
emit('change', item);
}
</script>
<template>
<ElSelect
:clearable="clearable"
:disabled="disabled"
:model-value="modelValue"
:placeholder="placeholder"
<div
v-bind="attrs"
class="w-full"
filterable
@change="handleChange"
:class="disabled ? 'cursor-not-allowed' : 'cursor-pointer'"
@click="handleClick"
@mouseenter="hovering = true"
@mouseleave="hovering = false"
>
<ElOption
v-for="item in list"
:key="item.id"
:label="item.name"
:value="item.id!"
/>
</ElSelect>
<ElTooltip :disabled="!selectedItem" placement="top" :show-after="500">
<template #content>
<div v-if="selectedItem" class="leading-6">
<div>设备编码{{ selectedItem.code || '-' }}</div>
<div>设备名称{{ selectedItem.name || '-' }}</div>
<div v-if="selectedItem.brand">{{ selectedItem.brand }}</div>
<div v-if="selectedItem.specification">
规格型号{{ selectedItem.specification }}
</div>
</div>
</template>
<ElInput
:disabled="disabled"
:model-value="displayLabel"
:placeholder="placeholder"
readonly
>
<template #suffix>
<CircleX v-if="showClear" class="size-4" />
<Search v-else class="size-4" />
</template>
</ElInput>
</ElTooltip>
</div>
<DvMachinerySelectDialog ref="dialogRef" @selected="handleSelected" />
</template>

View File

@ -273,3 +273,65 @@ export function useImportFormSchema(): VbenFormSchema[] {
},
];
}
/** 设备选择弹窗的搜索表单 */
export function useMachinerySelectGridFormSchema(): VbenFormSchema[] {
return [
{
fieldName: 'code',
label: '设备编码',
component: 'Input',
componentProps: {
clearable: true,
placeholder: '请输入设备编码',
},
},
{
fieldName: 'name',
label: '设备名称',
component: 'Input',
componentProps: {
clearable: true,
placeholder: '请输入设备名称',
},
},
{
fieldName: 'workshopId',
label: '所属车间',
component: markRaw(MdWorkshopSelect),
componentProps: {
clearable: true,
placeholder: '请选择所属车间',
},
},
];
}
/** 设备选择弹窗的字段 */
export function useMachinerySelectGridColumns(
multiple = false,
): VxeTableGridOptions<MesDvMachineryApi.Machinery>['columns'] {
return [
{ type: multiple ? 'checkbox' : 'radio', width: 50 },
{ field: 'code', title: '设备编码', width: 120 },
{ field: 'name', title: '设备名称', minWidth: 120 },
{ field: 'brand', title: '品牌', minWidth: 120 },
{ field: 'specification', title: '规格型号', minWidth: 120 },
{ field: 'workshopName', title: '所属车间', width: 120 },
{
field: 'status',
title: '设备状态',
width: 100,
cellRender: {
name: 'CellDict',
props: { type: DICT_TYPE.MES_DV_MACHINERY_STATUS },
},
},
{
field: 'createTime',
title: '创建时间',
width: 160,
formatter: 'formatDateTime',
},
];
}

View File

@ -2,15 +2,31 @@
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { MesWmProductSalesApi } from '#/api/mes/wm/productsales';
import { useVbenModal } from '@vben/common-ui';
import { DICT_TYPE } from '@vben/constants';
import { ElButton } from 'element-plus';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { getProductSalesPage } from '#/api/mes/wm/productsales';
import ProductSalesForm from '#/views/mes/wm/productsales/modules/form.vue';
const props = defineProps<{
clientId: number;
}>();
const [DetailModal, detailModalApi] = useVbenModal({
connectedComponent: ProductSalesForm,
destroyOnClose: true,
});
/** 查看销售出库单详情 */
function handleViewSales(row: MesWmProductSalesApi.ProductSales) {
if (row.id) {
detailModalApi.setData({ formType: 'detail', id: row.id }).open();
}
}
const [Grid] = useVbenVxeGrid({
gridOptions: {
columns: [
@ -18,6 +34,7 @@ const [Grid] = useVbenVxeGrid({
field: 'code',
title: '出库单编号',
minWidth: 160,
slots: { default: 'code' },
},
{
field: 'name',
@ -70,5 +87,12 @@ const [Grid] = useVbenVxeGrid({
</script>
<template>
<Grid table-title="" />
<DetailModal />
<Grid table-title="">
<template #code="{ row }">
<ElButton link type="primary" @click="handleViewSales(row)">
{{ row.code }}
</ElButton>
</template>
</Grid>
</template>

View File

@ -143,9 +143,7 @@ const [Modal, modalApi] = useVbenModal({
if (!ok) {
return;
}
//
ElMessage.success($t('ui.actionMessage.operationSuccess'));
await modalApi.close();
emit('success');
} finally {
modalApi.unlock();
@ -167,7 +165,10 @@ const [Modal, modalApi] = useVbenModal({
formType.value = data.formType;
formApi.setState({ schema: useFormSchema(formType.value, formApi) });
formApi.setDisabled(formType.value === 'detail');
modalApi.setState({ showConfirmButton: formType.value !== 'detail' });
modalApi.setState({
confirmText: formType.value === 'detail' ? undefined : '保存',
showConfirmButton: formType.value !== 'detail',
});
if (data?.id) {
modalApi.lock();
try {

View File

@ -1 +1,2 @@
export { default as TmToolSelectDialog } from './select-dialog.vue';
export { default as TmToolSelect } from './select.vue';

View File

@ -1,52 +1,139 @@
<script lang="ts" setup>
import type { MesTmToolApi } from '#/api/mes/tm/tool';
import { onMounted, ref } from 'vue';
import { computed, ref, useAttrs, watch } from 'vue';
import { ElOption, ElSelect } from 'element-plus';
import { CircleX, Search } from '@vben/icons';
import { getToolSimpleList } from '#/api/mes/tm/tool';
import { ElInput, ElTooltip } from 'element-plus';
withDefaults(
import { getTool } from '#/api/mes/tm/tool';
import TmToolSelectDialog from './select-dialog.vue';
defineOptions({ name: 'TmToolSelect', inheritAttrs: false });
const props = withDefaults(
defineProps<{
clearable?: boolean;
disabled?: boolean;
modelValue?: number;
placeholder?: string;
}>(),
{ clearable: true, disabled: false, modelValue: undefined, placeholder: '请选择工具' },
{
clearable: true,
disabled: false,
modelValue: undefined,
placeholder: '请选择工具',
},
);
const emit = defineEmits<{
change: [row?: MesTmToolApi.Tool];
'update:modelValue': [value?: number];
change: [item: MesTmToolApi.Tool | undefined];
'update:modelValue': [value: number | undefined];
}>();
const list = ref<MesTmToolApi.Tool[]>([]); //
const attrs = useAttrs(); //
const dialogRef = ref<InstanceType<typeof TmToolSelectDialog>>(); //
const hovering = ref(false); //
const selectedItem = ref<MesTmToolApi.Tool>(); //
/** 加载工具列表 */
async function getList() {
list.value = await getToolSimpleList();
const displayLabel = computed(() => selectedItem.value?.name ?? ''); //
const showClear = computed(
() =>
props.clearable &&
!props.disabled &&
hovering.value &&
props.modelValue != null,
);
/** 根据工具编号回显选择器 */
async function resolveItemById(id: number | undefined) {
if (id == null) {
selectedItem.value = undefined;
return;
}
if (selectedItem.value?.id === id) {
return;
}
selectedItem.value = await getTool(id);
}
/** 处理工具选择变化 */
function handleChange(value: number | string | undefined) {
const toolId = typeof value === 'number' ? value : undefined;
emit('update:modelValue', toolId);
emit('change', list.value.find((item) => item.id === toolId));
watch(
() => props.modelValue,
(value) => {
resolveItemById(value);
},
{ immediate: true },
);
/** 清空已选工具 */
function clearSelected() {
selectedItem.value = undefined;
emit('update:modelValue', undefined);
emit('change', undefined);
}
onMounted(getList);
/** 打开工具选择弹窗 */
function handleClick(event: MouseEvent) {
if (props.disabled) {
return;
}
const target = event.target as HTMLElement;
if (showClear.value && target.closest('.el-input__suffix')) {
event.stopPropagation();
clearSelected();
return;
}
const selectedIds = props.modelValue == null ? [] : [props.modelValue];
dialogRef.value?.open(selectedIds, { multiple: false });
}
/** 回填选中的工具 */
function handleSelected(rows: MesTmToolApi.Tool[]) {
const item = rows[0];
if (!item) {
return;
}
selectedItem.value = item;
emit('update:modelValue', item.id);
emit('change', item);
}
</script>
<template>
<ElSelect
:clearable="clearable"
:disabled="disabled"
:model-value="modelValue"
:placeholder="placeholder"
<div
v-bind="attrs"
class="w-full"
filterable
@change="handleChange"
:class="disabled ? 'cursor-not-allowed' : 'cursor-pointer'"
@click="handleClick"
@mouseenter="hovering = true"
@mouseleave="hovering = false"
>
<ElOption v-for="item in list" :key="item.id" :label="item.name" :value="item.id!" />
</ElSelect>
<ElTooltip :disabled="!selectedItem" placement="top" :show-after="500">
<template #content>
<div v-if="selectedItem" class="leading-6">
<div>工具编码{{ selectedItem.code || '-' }}</div>
<div>工具名称{{ selectedItem.name || '-' }}</div>
<div v-if="selectedItem.brand">{{ selectedItem.brand }}</div>
<div v-if="selectedItem.specification">
型号规格{{ selectedItem.specification }}
</div>
<div v-if="selectedItem.toolTypeName">
工具类型{{ selectedItem.toolTypeName }}
</div>
</div>
</template>
<ElInput
:disabled="disabled"
:model-value="displayLabel"
:placeholder="placeholder"
readonly
>
<template #suffix>
<CircleX v-if="showClear" class="size-4" />
<Search v-else class="size-4" />
</template>
</ElInput>
</ElTooltip>
</div>
<TmToolSelectDialog ref="dialogRef" @selected="handleSelected" />
</template>

View File

@ -328,3 +328,85 @@ export function useGridColumns(): VxeTableGridOptions<MesTmToolApi.Tool>['column
},
];
}
/** 工具选择弹窗的搜索表单 */
export function useToolSelectGridFormSchema(): VbenFormSchema[] {
return [
{
fieldName: 'code',
label: '工具编码',
component: 'Input',
componentProps: {
clearable: true,
placeholder: '请输入工具编码',
},
},
{
fieldName: 'name',
label: '工具名称',
component: 'Input',
componentProps: {
clearable: true,
placeholder: '请输入工具名称',
},
},
{
fieldName: 'toolTypeId',
label: '工具类型',
component: markRaw(TmToolTypeSelect),
componentProps: {
placeholder: '请选择工具类型',
},
},
{
fieldName: 'brand',
label: '品牌',
component: 'Input',
componentProps: {
clearable: true,
placeholder: '请输入品牌',
},
},
{
fieldName: 'status',
label: '状态',
component: 'Select',
componentProps: {
clearable: true,
options: getDictOptions(DICT_TYPE.MES_TM_TOOL_STATUS, 'number'),
placeholder: '请选择状态',
},
},
];
}
/** 工具选择弹窗的字段 */
export function useToolSelectGridColumns(
multiple = false,
): VxeTableGridOptions<MesTmToolApi.Tool>['columns'] {
return [
{ type: multiple ? 'checkbox' : 'radio', width: 50 },
{ field: 'code', title: '工具编码', width: 120 },
{ field: 'name', title: '工具名称', minWidth: 120 },
{ field: 'brand', title: '品牌', minWidth: 100 },
{ field: 'specification', title: '型号规格', minWidth: 100 },
{ field: 'toolTypeName', title: '工具类型', width: 120 },
{ field: 'quantity', title: '库存数量', width: 100 },
{ field: 'availableQuantity', title: '可用数量', width: 100 },
{
field: 'status',
title: '状态',
width: 100,
cellRender: {
name: 'CellDict',
props: { type: DICT_TYPE.MES_TM_TOOL_STATUS },
},
},
{
field: 'createTime',
title: '创建时间',
width: 180,
formatter: 'formatDateTime',
},
];
}

View File

@ -3,14 +3,16 @@ import type { VbenFormSchema } from '#/adapter/form';
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { MesWmSalesNoticeApi } from '#/api/mes/wm/salesnotice';
import { nextTick, ref } from 'vue';
import { markRaw, nextTick, ref } from 'vue';
import { DICT_TYPE } from '@vben/constants';
import { getDictOptions } from '@vben/hooks';
import { ElButton, ElDialog, ElMessage } from 'element-plus';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { getSalesNoticePage } from '#/api/mes/wm/salesnotice';
import { MdClientSelect } from '#/views/mes/md/client/components';
const emit = defineEmits<{
selected: [rows: MesWmSalesNoticeApi.SalesNotice[]];
@ -23,8 +25,8 @@ const syncingSingleSelection = ref(false); // 是否同步单选勾选状态
const selectedRows = ref<MesWmSalesNoticeApi.SalesNotice[]>([]); //
const preSelectedIds = ref<number[]>([]); //
/** 搜索表单 */
function useSearchSchema(): VbenFormSchema[] {
/** 搜索表单:未固定状态时展示状态下拉,固定状态时隐藏 */
function useSearchSchema(hasFixedStatus: boolean): VbenFormSchema[] {
return [
{
fieldName: 'code',
@ -53,6 +55,31 @@ function useSearchSchema(): VbenFormSchema[] {
placeholder: '请输入销售订单编号',
},
},
{
fieldName: 'clientId',
label: '客户',
component: markRaw(MdClientSelect),
componentProps: {
placeholder: '请选择客户',
},
},
...(hasFixedStatus
? []
: [
{
fieldName: 'status',
label: '单据状态',
component: 'Select',
componentProps: {
clearable: true,
options: getDictOptions(
DICT_TYPE.MES_WM_SALES_NOTICE_STATUS,
'number',
),
placeholder: '请选择单据状态',
},
} as VbenFormSchema,
]),
];
}
@ -165,7 +192,7 @@ function applyPreSelection() {
const [Grid, gridApi] = useVbenVxeGrid({
formOptions: {
schema: useSearchSchema(),
schema: useSearchSchema(false),
},
gridOptions: {
columns: useGridColumns(),
@ -182,8 +209,9 @@ const [Grid, gridApi] = useVbenVxeGrid({
return await getSalesNoticePage({
pageNo: page.currentPage,
pageSize: page.pageSize,
status: fixedStatus.value,
...formValues,
//
status: fixedStatus.value ?? formValues.status,
});
},
},
@ -219,6 +247,10 @@ async function openModal(
multiple.value = options?.multiple ?? false;
fixedStatus.value = options?.status;
preSelectedIds.value = selectedIds || [];
//
gridApi.formApi.setState({
schema: useSearchSchema(fixedStatus.value != null),
});
await nextTick();
await resetQueryState();
await gridApi.query();