From b176162c23294d8d1bfb9f09cf6bb759efb0124a Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期三, 15 七月 2026 14:10:26 +0800
Subject: [PATCH] 银川 1.库存现有量添加自定义出库入库功能 2.整理重复文件
---
src/views/wls/materialstock/components/batch-config-display.vue | 89 +---
src/views/wls/materialstock/components/stock-adjust-modal.vue | 205 +++++++----
src/views/basicData/mdm/modules/form.vue | 63 ---
src/views/erp/purchase/supplier/components/select.vue | 114 ++++++
src/views/wls/itemreceipt/data.ts | 6
/dev/null | 124 ------
vite.config.ts | 2
src/views/wls/batch/components/detail.vue | 54 ++
src/views/basicData/mdm/data.ts | 222 +++++++++---
src/views/basicData/mdm/index.vue | 34 +
src/views/erp/purchase/supplier/components/index.ts | 2
src/api/mes/wm/materialstock/index.ts | 4
src/api/mdm/item/index.ts | 10
src/views/erp/purchase/supplier/components/select-dialog.vue | 122 ++++--
14 files changed, 605 insertions(+), 446 deletions(-)
diff --git a/src/api/mdm/item/index.ts b/src/api/mdm/item/index.ts
index 275a7da..564287f 100644
--- a/src/api/mdm/item/index.ts
+++ b/src/api/mdm/item/index.ts
@@ -37,6 +37,16 @@
warehouseName?: string;
remark?: string;
createTime?: string;
+ // 鍚屾鐩稿叧瀛楁
+ syncMes?: boolean;
+ // 鎵规灞炴�ч厤缃瓧娈�
+ produceDateFlag?: boolean;
+ expireDateFlag?: boolean;
+ receiptDateFlag?: boolean;
+ vendorFlag?: boolean;
+ purchaseOrderCodeFlag?: boolean;
+ lotNumberFlag?: boolean;
+ qualityStatusFlag?: boolean;
}
/** 鐗╂枡鍒嗛〉鏌ヨ鍙傛暟 */
diff --git a/src/api/mes/wm/materialstock/index.ts b/src/api/mes/wm/materialstock/index.ts
index 02c3e94..97f95b1 100644
--- a/src/api/mes/wm/materialstock/index.ts
+++ b/src/api/mes/wm/materialstock/index.ts
@@ -74,7 +74,11 @@
batchCode?: string; // 鎵规鍙凤紙鏂板缓鎵规鏃朵紶鍏ワ級
produceDate?: string; // 鐢熶骇鏃ユ湡锛堟柊寤烘壒娆℃椂浼犲叆锛�
expireDate?: string; // 鏈夋晥鏈燂紙鏂板缓鎵规鏃朵紶鍏ワ級
+ receiptDate?: string; // 鍏ュ簱鏃ユ湡
vendorId?: number; // 渚涘簲鍟咺D
+ purchaseOrderCode?: string; // 閲囪喘璁㈠崟鍙�
+ lotNumber?: string; // 鐢熶骇鎵瑰彿
+ qualityStatus?: string; // 璐ㄩ噺鐘舵��
quantity: number; // 鍏ュ簱鏁伴噺锛堝繀椤诲ぇ浜�0锛�
reason?: string; // 鍏ュ簱鍘熷洜
}
diff --git a/src/views/arrivalnotice/components/index.ts b/src/views/arrivalnotice/components/index.ts
deleted file mode 100644
index 9f30fda..0000000
--- a/src/views/arrivalnotice/components/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export { default as WmArrivalNoticeLineSelect } from './line-select.vue';
-export { default as WmArrivalNoticeSelect } from './select.vue';
diff --git a/src/views/arrivalnotice/components/line-select-dialog.vue b/src/views/arrivalnotice/components/line-select-dialog.vue
deleted file mode 100644
index 8081565..0000000
--- a/src/views/arrivalnotice/components/line-select-dialog.vue
+++ /dev/null
@@ -1,203 +0,0 @@
-<script lang="ts" setup>
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmArrivalNoticeLineApi } from '#/api/mes/wm/arrivalnotice/line';
-
-import { nextTick, ref } from 'vue';
-
-import { DICT_TYPE } from '@vben/constants';
-
-import { message, Modal } from 'ant-design-vue';
-
-import { useVbenVxeGrid } from '#/adapter/vxe-table';
-import { getArrivalNoticeLinePage } from '#/api/mes/wm/arrivalnotice/line';
-
-const emit = defineEmits<{
- selected: [rows: MesWmArrivalNoticeLineApi.ArrivalNoticeLine[]];
-}>();
-
-const open = ref(false); // 寮圭獥鏄惁鎵撳紑
-const noticeId = ref<number>(); // 鎵�灞為�氱煡鍗曠紪鍙�
-const syncingSingleSelection = ref(false); // 鏄惁鍚屾鍗曢�夊嬀閫夌姸鎬�
-const selectedRows = ref<MesWmArrivalNoticeLineApi.ArrivalNoticeLine[]>([]); // 宸查�夎鍒楄〃
-const preSelectedIds = ref<number[]>([]); // 棰勯�夎缂栧彿鍒楄〃
-
-/** 琛ㄦ牸瀛楁 */
-function useGridColumns(): VxeTableGridOptions<MesWmArrivalNoticeLineApi.ArrivalNoticeLine>['columns'] {
- return [
- {
- type: 'checkbox',
- width: 50,
- },
- {
- field: 'itemCode',
- title: '鐗╂枡缂栫爜',
- minWidth: 120,
- },
- {
- field: 'itemName',
- title: '鐗╂枡鍚嶇О',
- minWidth: 140,
- },
- {
- field: 'specification',
- title: '瑙勬牸鍨嬪彿',
- minWidth: 120,
- },
- {
- field: 'unitMeasureName',
- title: '鍗曚綅',
- width: 80,
- },
- {
- field: 'arrivalQuantity',
- title: '鍒拌揣鏁伴噺',
- width: 100,
- },
- {
- field: 'iqcCheckFlag',
- title: '鏄惁妫�楠�',
- width: 90,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.INFRA_BOOLEAN_STRING },
- },
- },
- {
- field: 'qualifiedQuantity',
- title: '鍚堟牸鏁伴噺',
- width: 100,
- },
- {
- field: 'remark',
- title: '澶囨敞',
- minWidth: 120,
- },
- ];
-}
-
-/** 鍗曢�夋ā寮忎笅鍚屾 VXE 鍕鹃�夌姸鎬� */
-async function syncSingleSelection(
- row?: MesWmArrivalNoticeLineApi.ArrivalNoticeLine,
-) {
- syncingSingleSelection.value = true;
- await nextTick();
- await gridApi.grid.clearCheckboxRow();
- if (row) {
- await gridApi.grid.setCheckboxRow(row, true);
- }
- await nextTick();
- syncingSingleSelection.value = false;
-}
-
-/** 澶勭悊鍕鹃�夊彉鍖栵紝鍙繚鐣欐渶鍚庝竴鏉� */
-async function handleCheckboxChange({
- checked,
- row,
-}: {
- checked: boolean;
- row?: MesWmArrivalNoticeLineApi.ArrivalNoticeLine;
-}) {
- if (syncingSingleSelection.value) {
- return;
- }
- const selected = checked && row ? [row] : [];
- selectedRows.value = selected;
- await syncSingleSelection(selected[0]);
-}
-
-/** 鍥炴樉棰勯�夎 */
-function applyPreSelection() {
- if (preSelectedIds.value.length === 0) {
- return;
- }
- const rows =
- gridApi.grid.getData() as MesWmArrivalNoticeLineApi.ArrivalNoticeLine[];
- for (const row of rows) {
- if (row.id && preSelectedIds.value.includes(row.id)) {
- gridApi.grid.setCheckboxRow(row, true);
- selectedRows.value = [row];
- }
- }
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- gridOptions: {
- columns: useGridColumns(),
- height: 460,
- keepSource: true,
- checkboxConfig: {
- highlight: true,
- reserve: true,
- },
- proxyConfig: {
- ajax: {
- query: async ({ page }) => {
- if (!noticeId.value) {
- return { list: [], total: 0 };
- }
- return await getArrivalNoticeLinePage({
- noticeId: noticeId.value,
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- },
- } as VxeTableGridOptions<MesWmArrivalNoticeLineApi.ArrivalNoticeLine>,
- gridEvents: {
- checkboxChange: handleCheckboxChange,
- },
-});
-
-/** 鎵撳紑琛岄�夋嫨寮圭獥 */
-async function openModal(id: number | undefined, selectedIds?: number[]) {
- open.value = true;
- noticeId.value = id;
- preSelectedIds.value = selectedIds || [];
- selectedRows.value = [];
- await nextTick();
- await gridApi.grid.clearCheckboxRow();
- await gridApi.query();
- await nextTick();
- applyPreSelection();
-}
-
-/** 鍏抽棴寮圭獥 */
-async function closeModal() {
- open.value = false;
- selectedRows.value = [];
- await gridApi.grid.clearCheckboxRow();
-}
-
-/** 纭閫夋嫨琛� */
-function handleConfirm() {
- if (selectedRows.value.length === 0) {
- message.warning('璇烽�夋嫨涓�鏉℃暟鎹�');
- return;
- }
- emit('selected', [selectedRows.value[0]!]);
- open.value = false;
-}
-
-defineExpose({ open: openModal });
-</script>
-
-<template>
- <Modal
- v-model:open="open"
- title="鍒拌揣閫氱煡鍗曡閫夋嫨"
- width="70%"
- :destroy-on-close="true"
- @cancel="closeModal"
- @ok="handleConfirm"
- >
- <Grid table-title="鍒拌揣閫氱煡鍗曡鍒楄〃" />
- </Modal>
-</template>
diff --git a/src/views/arrivalnotice/components/line-select.vue b/src/views/arrivalnotice/components/line-select.vue
deleted file mode 100644
index 09e85ab..0000000
--- a/src/views/arrivalnotice/components/line-select.vue
+++ /dev/null
@@ -1,153 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmArrivalNoticeLineApi } from '#/api/mes/wm/arrivalnotice/line';
-
-import { computed, ref, useAttrs, watch } from 'vue';
-
-import { IconifyIcon } from '@vben/icons';
-
-import { Input, Tooltip } from 'ant-design-vue';
-
-import { getArrivalNoticeLine } from '#/api/mes/wm/arrivalnotice/line';
-
-import WmArrivalNoticeLineSelectDialog from './line-select-dialog.vue';
-
-defineOptions({ name: 'WmArrivalNoticeLineSelect', inheritAttrs: false });
-
-const props = withDefaults(
- defineProps<{
- allowClear?: boolean;
- disabled?: boolean;
- modelValue?: number;
- noticeId?: number; // 鎵�灞炲埌璐ч�氱煡鍗曠紪鍙�
- placeholder?: string;
- }>(),
- {
- allowClear: true,
- disabled: false,
- modelValue: undefined,
- noticeId: undefined,
- placeholder: '璇烽�夋嫨鍒拌揣閫氱煡鍗曡',
- },
-);
-
-const emit = defineEmits<{
- change: [item: MesWmArrivalNoticeLineApi.ArrivalNoticeLine | undefined];
- 'update:modelValue': [value: number | undefined];
-}>();
-
-const attrs = useAttrs();
-const dialogRef = ref<InstanceType<typeof WmArrivalNoticeLineSelectDialog>>();
-const hovering = ref(false);
-const selectedItem = ref<MesWmArrivalNoticeLineApi.ArrivalNoticeLine>();
-
-const displayLabel = computed(() => {
- const item = selectedItem.value;
- if (!item) {
- return '';
- }
- return `${item.itemCode ?? ''} - ${item.itemName ?? ''}`;
-});
-
-const showClear = computed(
- () =>
- props.allowClear &&
- !props.disabled &&
- hovering.value &&
- props.modelValue !== null,
-);
-
-/** 鏍规嵁缂栧彿鍗曟潯鏌ヨ琛屼俊鎭紙鐢ㄤ簬缂栬緫鍥炴樉锛� */
-async function resolveItemById(id: number | undefined) {
- if (!id) {
- selectedItem.value = undefined;
- return;
- }
- if (selectedItem.value?.id === id) {
- return;
- }
- selectedItem.value = await getArrivalNoticeLine(id);
-}
-
-watch(() => props.modelValue, resolveItemById, { immediate: true });
-
-/** noticeId 鍙樺寲鏃舵竻绌洪�変腑锛堝叧鑱旂殑琛屽凡澶辨晥锛� */
-watch(
- () => props.noticeId,
- () => {
- selectedItem.value = undefined;
- emit('update:modelValue', undefined);
- emit('change', undefined);
- },
-);
-
-/** 娓呯┖宸查�夎 */
-function clearSelected() {
- selectedItem.value = undefined;
- emit('update:modelValue', undefined);
- emit('change', undefined);
-}
-
-/** 鎵撳紑琛岄�夋嫨寮圭獥 */
-function handleClick(event: MouseEvent) {
- if (props.disabled || !props.noticeId) {
- 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]
- ) as number[];
- dialogRef.value?.open(props.noticeId, selectedIds);
-}
-
-/** 寮圭獥閫変腑鍥炶皟 */
-function handleSelected(rows: MesWmArrivalNoticeLineApi.ArrivalNoticeLine[]) {
- const item = rows[0];
- if (!item) {
- return;
- }
- selectedItem.value = item;
- emit('update:modelValue', item.id);
- emit('change', item);
-}
-</script>
-
-<template>
- <div
- v-bind="attrs"
- class="w-full"
- :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.itemCode || '-' }}</div>
- <div>鐗╂枡鍚嶇О锛歿{ selectedItem.itemName || '-' }}</div>
- <div>瑙勬牸鍨嬪彿锛歿{ selectedItem.specification || '-' }}</div>
- <div>鍒拌揣鏁伴噺锛歿{ selectedItem.arrivalQuantity ?? '-' }}</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>
- <WmArrivalNoticeLineSelectDialog ref="dialogRef" @selected="handleSelected" />
-</template>
diff --git a/src/views/arrivalnotice/components/select-dialog.vue b/src/views/arrivalnotice/components/select-dialog.vue
deleted file mode 100644
index 5e1e6ef..0000000
--- a/src/views/arrivalnotice/components/select-dialog.vue
+++ /dev/null
@@ -1,288 +0,0 @@
-<script lang="ts" setup>
-import type { VbenFormSchema } from '#/adapter/form';
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmArrivalNoticeApi } from '#/api/mes/wm/arrivalnotice';
-
-import { nextTick, ref } from 'vue';
-
-import { DICT_TYPE } from '@vben/constants';
-
-import { message, Modal } from 'ant-design-vue';
-
-import { useVbenVxeGrid } from '#/adapter/vxe-table';
-import { getArrivalNoticePage } from '#/api/mes/wm/arrivalnotice';
-
-const emit = defineEmits<{
- selected: [rows: MesWmArrivalNoticeApi.ArrivalNotice[]];
-}>();
-
-const open = ref(false); // 寮圭獥鏄惁鎵撳紑
-const multiple = ref(false); // 鏄惁澶氶��
-const fixedStatus = ref<number>(); // 鍥哄畾鐘舵�佺瓫閫�
-const selectedRows = ref<MesWmArrivalNoticeApi.ArrivalNotice[]>([]); // 宸查�夐�氱煡鍗曞垪琛�
-const preSelectedIds = ref<number[]>([]); // 棰勯�夐�氱煡鍗曠紪鍙峰垪琛�
-
-/** 鎼滅储琛ㄥ崟 */
-function useSearchSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'code',
- label: '閫氱煡鍗曠紪鍙�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ラ�氱煡鍗曠紪鍙�',
- },
- },
- {
- fieldName: 'name',
- label: '閫氱煡鍗曞悕绉�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ラ�氱煡鍗曞悕绉�',
- },
- },
- {
- fieldName: 'purchaseOrderCode',
- label: '閲囪喘璁㈠崟缂栧彿',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ラ噰璐鍗曠紪鍙�',
- },
- },
- ];
-}
-
-/** 琛ㄦ牸瀛楁 */
-function useGridColumns(
- multipleSelect = false,
-): VxeTableGridOptions<MesWmArrivalNoticeApi.ArrivalNotice>['columns'] {
- return [
- {
- type: multipleSelect ? 'checkbox' : 'radio',
- width: 50,
- },
- {
- field: 'code',
- title: '閫氱煡鍗曠紪鍙�',
- minWidth: 160,
- },
- {
- field: 'name',
- title: '閫氱煡鍗曞悕绉�',
- minWidth: 150,
- },
- {
- field: 'purchaseOrderCode',
- title: '閲囪喘璁㈠崟缂栧彿',
- minWidth: 140,
- },
- {
- field: 'vendorName',
- title: '渚涘簲鍟嗗悕绉�',
- minWidth: 120,
- },
- {
- field: 'arrivalDate',
- title: '鍒拌揣鏃ユ湡',
- width: 120,
- formatter: 'formatDate',
- },
- {
- field: 'status',
- title: '鍗曟嵁鐘舵��',
- width: 100,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_ARRIVAL_NOTICE_STATUS },
- },
- },
- ];
-}
-
-/** 鑾峰彇澶氶�夎褰曪紝鍖呭惈 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()];
-}
-
-/** 澶勭悊澶氶�夊嬀閫夊彉鍖� */
-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,
-}: {
- row: MesWmArrivalNoticeApi.ArrivalNotice;
-}) {
- if (multiple.value) {
- await toggleMultipleRow(row);
- return;
- }
- selectedRows.value = [row];
- await gridApi.grid.setRadioRow(row);
- handleConfirm();
-}
-
-/** 鍥炴樉棰勯�夐�氱煡鍗� */
-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 === 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();
- }
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- formOptions: {
- schema: useSearchSchema(),
- },
- gridOptions: {
- columns: useGridColumns(false),
- height: 520,
- keepSource: true,
- checkboxConfig: {
- highlight: true,
- range: true,
- reserve: true,
- },
- radioConfig: {
- highlight: true,
- trigger: 'row',
- },
- proxyConfig: {
- ajax: {
- query: async ({ page }, formValues) => {
- return await getArrivalNoticePage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- status: fixedStatus.value,
- ...formValues,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- search: true,
- },
- } as VxeTableGridOptions<MesWmArrivalNoticeApi.ArrivalNotice>,
- gridEvents: {
- cellDblclick: handleCellDblclick,
- checkboxAll: handleCheckboxSelectChange,
- checkboxChange: handleCheckboxSelectChange,
- radioChange: ({ row }: { row: MesWmArrivalNoticeApi.ArrivalNotice }) => {
- handleRadioChange(row);
- },
- },
-});
-
-/** 閲嶇疆鏌ヨ鍜岄�夋嫨鐘舵�� */
-async function resetQueryState() {
- selectedRows.value = [];
- await gridApi.grid.clearCheckboxRow();
- await gridApi.grid.clearCheckboxReserve();
- await gridApi.grid.clearRadioRow();
- await gridApi.formApi.resetForm();
-}
-
-/** 鎵撳紑閫氱煡鍗曢�夋嫨寮圭獥 */
-async function openModal(
- selectedIds?: number[],
- options?: { multiple?: boolean; status?: number },
-) {
- open.value = true;
- multiple.value = options?.multiple ?? false;
- fixedStatus.value = options?.status;
- preSelectedIds.value = selectedIds || [];
- await nextTick();
- gridApi.setGridOptions({
- columns: useGridColumns(multiple.value),
- });
- await resetQueryState();
- await gridApi.query();
- await nextTick();
- await applyPreSelection();
-}
-
-/** 鍏抽棴閫氱煡鍗曢�夋嫨寮圭獥 */
-async function closeModal() {
- open.value = false;
- await resetQueryState();
-}
-
-/** 纭閫夋嫨閫氱煡鍗� */
-function handleConfirm() {
- if (selectedRows.value.length === 0) {
- message.warning(multiple.value ? '璇疯嚦灏戦�夋嫨涓�鏉℃暟鎹�' : '璇烽�夋嫨涓�鏉℃暟鎹�');
- return;
- }
- emit(
- 'selected',
- multiple.value ? selectedRows.value : [selectedRows.value[0]!],
- );
- open.value = false;
-}
-
-defineExpose({ open: openModal });
-</script>
-
-<template>
- <Modal
- v-model:open="open"
- title="鍒拌揣閫氱煡鍗曢�夋嫨"
- width="70%"
- :destroy-on-close="true"
- @cancel="closeModal"
- @ok="handleConfirm"
- >
- <Grid table-title="鍒拌揣閫氱煡鍗曞垪琛�" />
- </Modal>
-</template>
diff --git a/src/views/arrivalnotice/components/select.vue b/src/views/arrivalnotice/components/select.vue
deleted file mode 100644
index a0afffc..0000000
--- a/src/views/arrivalnotice/components/select.vue
+++ /dev/null
@@ -1,141 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmArrivalNoticeApi } from '#/api/mes/wm/arrivalnotice';
-
-import { computed, ref, useAttrs, watch } from 'vue';
-
-import { IconifyIcon } from '@vben/icons';
-
-import { Input, Tooltip } from 'ant-design-vue';
-
-import { getArrivalNotice } from '#/api/mes/wm/arrivalnotice';
-
-import WmArrivalNoticeSelectDialog from './select-dialog.vue';
-
-defineOptions({ name: 'WmArrivalNoticeSelect', inheritAttrs: false });
-
-const props = withDefaults(
- defineProps<{
- allowClear?: boolean;
- disabled?: boolean;
- modelValue?: number;
- placeholder?: string;
- status?: number; // 鍥哄畾鐘舵�佺瓫閫�
- }>(),
- {
- allowClear: true,
- disabled: false,
- modelValue: undefined,
- placeholder: '璇烽�夋嫨鍒拌揣閫氱煡鍗�',
- status: undefined,
- },
-);
-
-const emit = defineEmits<{
- change: [item: MesWmArrivalNoticeApi.ArrivalNotice | undefined];
- 'update:modelValue': [value: number | undefined];
-}>();
-
-const attrs = useAttrs();
-const dialogRef = ref<InstanceType<typeof WmArrivalNoticeSelectDialog>>();
-const hovering = ref(false);
-const selectedItem = ref<MesWmArrivalNoticeApi.ArrivalNotice>();
-
-const displayLabel = computed(() => selectedItem.value?.code ?? '');
-
-const showClear = computed(
- () =>
- props.allowClear &&
- !props.disabled &&
- hovering.value &&
- props.modelValue !== undefined &&
- props.modelValue !== null,
-);
-
-/** 鏍规嵁缂栧彿鍗曟潯鏌ヨ閫氱煡鍗曚俊鎭紙鐢ㄤ簬缂栬緫鍥炴樉锛� */
-async function resolveItemById(id: number | undefined) {
- if (!id) {
- selectedItem.value = undefined;
- return;
- }
- if (selectedItem.value?.id === id) {
- return;
- }
- selectedItem.value = await getArrivalNotice(id);
-}
-
-watch(() => props.modelValue, resolveItemById, { 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]
- ) as number[];
- dialogRef.value?.open(selectedIds, {
- multiple: false,
- status: props.status,
- });
-}
-
-/** 寮圭獥閫変腑鍥炶皟 */
-function handleSelected(rows: MesWmArrivalNoticeApi.ArrivalNotice[]) {
- const item = rows[0];
- if (!item) {
- return;
- }
- selectedItem.value = item;
- emit('update:modelValue', item.id);
- emit('change', item);
-}
-</script>
-
-<template>
- <div
- v-bind="attrs"
- class="w-full"
- :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>渚涘簲鍟嗭細{{ selectedItem.vendorName || '-' }}</div>
- <div>閲囪喘璁㈠崟锛歿{ selectedItem.purchaseOrderCode || '-' }}</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>
- <WmArrivalNoticeSelectDialog ref="dialogRef" @selected="handleSelected" />
-</template>
diff --git a/src/views/arrivalnotice/data.ts b/src/views/arrivalnotice/data.ts
deleted file mode 100644
index 0d7679a..0000000
--- a/src/views/arrivalnotice/data.ts
+++ /dev/null
@@ -1,352 +0,0 @@
-import type { VbenFormApi, VbenFormSchema } from '#/adapter/form';
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmArrivalNoticeApi } from '#/api/mes/wm/arrivalnotice';
-import type { MesWmArrivalNoticeLineApi } from '#/api/mes/wm/arrivalnotice/line';
-
-import { h, markRaw } from 'vue';
-
-import { DICT_TYPE, MesAutoCodeRuleCode } from '@vben/constants';
-
-import { Button } from 'ant-design-vue';
-
-import { z } from '#/adapter/form';
-import { generateAutoCode } from '#/api/mes/md/autocode/record';
-import { getRangePickerDefaultProps } from '#/utils';
-import { MdItemSelect } from '#/views/mes/md/item/components';
-import { MdVendorSelect } from '#/views/mes/md/vendor/components';
-
-/** 琛ㄥ崟绫诲瀷 */
-export type FormType = 'create' | 'detail' | 'update';
-
-/** 鏂板/淇敼鐨勮〃鍗� */
-export function useFormSchema(
- formType: FormType,
- formApi?: VbenFormApi,
-): VbenFormSchema[] {
- return [
- {
- fieldName: 'id',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'status',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'code',
- label: '閫氱煡鍗曠紪鍙�',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ラ�氱煡鍗曠紪鍙�',
- },
- rules: 'required',
- suffix:
- formType === 'detail'
- ? undefined
- : () =>
- h(
- Button,
- {
- type: 'default',
- onClick: async () => {
- const code = await generateAutoCode(
- MesAutoCodeRuleCode.WM_ARRIVAL_NOTICE_CODE,
- );
- await formApi?.setFieldValue('code', code);
- },
- },
- { default: () => '鐢熸垚' },
- ),
- },
- {
- fieldName: 'name',
- label: '閫氱煡鍗曞悕绉�',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ラ�氱煡鍗曞悕绉�',
- },
- rules: 'required',
- },
- {
- fieldName: 'purchaseOrderCode',
- label: '閲囪喘璁㈠崟缂栧彿',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ラ噰璐鍗曠紪鍙�',
- },
- },
- {
- fieldName: 'vendorId',
- label: '渚涘簲鍟�',
- component: markRaw(MdVendorSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨渚涘簲鍟�',
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'arrivalDate',
- label: '鍒拌揣鏃ユ湡',
- component: 'DatePicker',
- componentProps: {
- class: '!w-full',
- format: 'YYYY-MM-DD',
- placeholder: '璇烽�夋嫨鍒拌揣鏃ユ湡',
- valueFormat: 'x',
- },
- rules: 'required',
- },
- {
- fieldName: 'contactName',
- label: '鑱旂郴浜�',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ヨ仈绯讳汉',
- },
- },
- {
- fieldName: 'contactTelephone',
- label: '鑱旂郴鏂瑰紡',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ヨ仈绯绘柟寮�',
- },
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勬悳绱㈣〃鍗� */
-export function useGridFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'code',
- label: '閫氱煡鍗曠紪鍙�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ラ�氱煡鍗曠紪鍙�',
- },
- },
- {
- fieldName: 'name',
- label: '閫氱煡鍗曞悕绉�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ラ�氱煡鍗曞悕绉�',
- },
- },
- {
- fieldName: 'purchaseOrderCode',
- label: '閲囪喘璁㈠崟缂栧彿',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ラ噰璐鍗曠紪鍙�',
- },
- },
- {
- fieldName: 'vendorId',
- label: '渚涘簲鍟�',
- component: markRaw(MdVendorSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨渚涘簲鍟�',
- },
- },
- {
- fieldName: 'arrivalDate',
- label: '鍒拌揣鏃ユ湡',
- component: 'RangePicker',
- componentProps: {
- ...getRangePickerDefaultProps(),
- allowClear: true,
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勫瓧娈� */
-export function useGridColumns(): VxeTableGridOptions<MesWmArrivalNoticeApi.ArrivalNotice>['columns'] {
- return [
- {
- field: 'code',
- title: '閫氱煡鍗曠紪鍙�',
- minWidth: 160,
- slots: { default: 'code' },
- },
- {
- field: 'name',
- title: '閫氱煡鍗曞悕绉�',
- minWidth: 150,
- },
- {
- field: 'purchaseOrderCode',
- title: '閲囪喘璁㈠崟缂栧彿',
- minWidth: 140,
- },
- {
- field: 'vendorName',
- title: '渚涘簲鍟嗗悕绉�',
- minWidth: 120,
- },
- {
- field: 'contactName',
- title: '鑱旂郴浜�',
- minWidth: 100,
- },
- {
- field: 'contactTelephone',
- title: '鑱旂郴鏂瑰紡',
- minWidth: 120,
- },
- {
- field: 'arrivalDate',
- title: '鍒拌揣鏃ユ湡',
- width: 180,
- formatter: 'formatDate',
- },
- {
- field: 'status',
- title: '鍗曟嵁鐘舵��',
- minWidth: 100,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_ARRIVAL_NOTICE_STATUS },
- },
- },
- {
- title: '鎿嶄綔',
- width: 180,
- fixed: 'right',
- slots: { default: 'actions' },
- },
- ];
-}
-
-/** 閫氱煡鍗曡瀛愯〃鐨勫瓧娈� */
-export function useLineGridColumns(
- editable: boolean,
-): VxeTableGridOptions<MesWmArrivalNoticeLineApi.ArrivalNoticeLine>['columns'] {
- return [
- {
- field: 'itemCode',
- title: '鐗╂枡缂栫爜',
- minWidth: 120,
- },
- {
- field: 'itemName',
- title: '鐗╂枡鍚嶇О',
- minWidth: 140,
- },
- {
- field: 'specification',
- title: '瑙勬牸鍨嬪彿',
- minWidth: 120,
- },
- {
- field: 'unitMeasureName',
- title: '鍗曚綅',
- width: 80,
- },
- {
- field: 'arrivalQuantity',
- title: '鍒拌揣鏁伴噺',
- width: 100,
- },
- {
- field: 'iqcCheckFlag',
- title: '鏄惁妫�楠�',
- width: 90,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.INFRA_BOOLEAN_STRING },
- },
- },
- {
- field: 'qualifiedQuantity',
- title: '鍚堟牸鏁伴噺',
- width: 100,
- },
- {
- field: 'iqcCode',
- title: '妫�楠屽崟鍙�',
- minWidth: 140,
- },
- {
- field: 'remark',
- title: '澶囨敞',
- minWidth: 120,
- },
- ...(editable
- ? [
- {
- title: '鎿嶄綔',
- width: 120,
- fixed: 'right',
- slots: { default: 'actions' },
- } as const,
- ]
- : []),
- ];
-}
-
-/** 閫氱煡鍗曡鏂板/淇敼鐨勮〃鍗� */
-export function useLineFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'itemId',
- label: '鐗╂枡',
- component: markRaw(MdItemSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨鐗╂枡',
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'arrivalQuantity',
- label: '鍒拌揣鏁伴噺',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0.01,
- placeholder: '璇疯緭鍏ュ埌璐ф暟閲�',
- precision: 2,
- },
- rules: 'required',
- },
- {
- fieldName: 'iqcCheckFlag',
- label: '鏄惁妫�楠�',
- component: 'Switch',
- rules: z.boolean().default(false),
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
diff --git a/src/views/arrivalnotice/index.vue b/src/views/arrivalnotice/index.vue
deleted file mode 100644
index c2c0a64..0000000
--- a/src/views/arrivalnotice/index.vue
+++ /dev/null
@@ -1,179 +0,0 @@
-<script lang="ts" setup>
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmArrivalNoticeApi } from '#/api/mes/wm/arrivalnotice';
-
-import { Page, useVbenModal } from '@vben/common-ui';
-import { MesWmArrivalNoticeStatusEnum } from '@vben/constants';
-import { downloadFileFromBlobPart } from '@vben/utils';
-
-import { Button, message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import {
- deleteArrivalNotice,
- exportArrivalNotice,
- getArrivalNoticePage,
-} from '#/api/mes/wm/arrivalnotice';
-import { $t } from '#/locales';
-
-import { useGridColumns, useGridFormSchema } from './data';
-import Form from './modules/form.vue';
-
-const [FormModal, formModalApi] = useVbenModal({
- connectedComponent: Form,
- destroyOnClose: true,
-});
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- gridApi.query();
-}
-
-/** 鍒涘缓鍒拌揣閫氱煡鍗� */
-function handleCreate() {
- formModalApi.setData({ formType: 'create' }).open();
-}
-
-/** 鏌ョ湅鍒拌揣閫氱煡鍗� */
-function handleDetail(row: MesWmArrivalNoticeApi.ArrivalNotice) {
- formModalApi.setData({ formType: 'detail', id: row.id }).open();
-}
-
-/** 缂栬緫鍒拌揣閫氱煡鍗� */
-function handleEdit(row: MesWmArrivalNoticeApi.ArrivalNotice) {
- formModalApi.setData({ formType: 'update', id: row.id }).open();
-}
-
-/** 鍒犻櫎鍒拌揣閫氱煡鍗� */
-async function handleDelete(row: MesWmArrivalNoticeApi.ArrivalNotice) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.code]),
- duration: 0,
- });
- try {
- await deleteArrivalNotice(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.code]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-/** 鎻愮ず鍓嶅線璐ㄦ妯″潡 */
-function handleQc() {
- message.info('璇峰墠寰�銆愯川閲忕鐞� - 寰呮浠诲姟銆戜腑杩涜鏉ユ枡妫�楠屾搷浣�');
-}
-
-/** 鎻愮ず鍓嶅線閲囪喘鍏ュ簱妯″潡 */
-function handleReceipt() {
- message.info('璇峰墠寰�銆愪粨搴撶鐞� - 閲囪喘鍏ュ簱銆戜腑杩涜鍏ュ簱鎿嶄綔');
-}
-
-/** 瀵煎嚭琛ㄦ牸 */
-async function handleExport() {
- const data = await exportArrivalNotice(await gridApi.formApi.getValues());
- downloadFileFromBlobPart({ fileName: '鍒拌揣閫氱煡鍗�.xls', source: data });
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- formOptions: {
- schema: useGridFormSchema(),
- },
- gridOptions: {
- columns: useGridColumns(),
- height: 'auto',
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }, formValues) => {
- return await getArrivalNoticePage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- ...formValues,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- search: true,
- },
- } as VxeTableGridOptions<MesWmArrivalNoticeApi.ArrivalNotice>,
-});
-</script>
-
-<template>
- <Page auto-content-height><FormModal @success="handleRefresh" />
-
- <Grid table-title="鍒拌揣閫氱煡鍗曞垪琛�">
- <template #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: $t('ui.actionTitle.create', ['鍒拌揣閫氱煡鍗�']),
- type: 'primary',
- icon: ACTION_ICON.ADD,
- auth: ['mes:wm-arrival-notice:create'],
- onClick: handleCreate,
- },
- {
- label: $t('ui.actionTitle.export'),
- type: 'primary',
- icon: ACTION_ICON.DOWNLOAD,
- auth: ['mes:wm-arrival-notice:export'],
- onClick: handleExport,
- },
- ]"
- />
- </template>
- <template #code="{ row }">
- <Button type="link" @click="handleDetail(row)">
- {{ row.code }}
- </Button>
- </template>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- auth: ['mes:wm-arrival-notice:update'],
- ifShow: row.status === MesWmArrivalNoticeStatusEnum.PREPARE,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- auth: ['mes:wm-arrival-notice:delete'],
- ifShow: row.status === MesWmArrivalNoticeStatusEnum.PREPARE,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.code]),
- confirm: handleDelete.bind(null, row),
- },
- },
- {
- label: '鎵ц璐ㄦ',
- type: 'link',
- ifShow: row.status === MesWmArrivalNoticeStatusEnum.PENDING_QC,
- onClick: handleQc,
- },
- {
- label: '鎵ц鍏ュ簱',
- type: 'link',
- ifShow:
- row.status === MesWmArrivalNoticeStatusEnum.PENDING_RECEIPT,
- onClick: handleReceipt,
- },
- ]"
- />
- </template>
- </Grid>
- </Page>
-</template>
diff --git a/src/views/arrivalnotice/modules/form.vue b/src/views/arrivalnotice/modules/form.vue
deleted file mode 100644
index 1f4224b..0000000
--- a/src/views/arrivalnotice/modules/form.vue
+++ /dev/null
@@ -1,171 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { MesWmArrivalNoticeApi } from '#/api/mes/wm/arrivalnotice';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-import { MesWmArrivalNoticeStatusEnum } from '@vben/constants';
-
-import { Button, Divider, message, Popconfirm } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createArrivalNotice,
- getArrivalNotice,
- submitArrivalNotice,
- updateArrivalNotice,
-} from '#/api/mes/wm/arrivalnotice';
-import { $t } from '#/locales';
-
-import { useFormSchema } from '../data';
-import LineList from './line-list.vue';
-
-const emit = defineEmits(['success']);
-const formType = ref<FormType>('create');
-const formData = ref<MesWmArrivalNoticeApi.ArrivalNotice>();
-const originalSnapshot = ref(''); // 琛ㄥ崟鍘熷鏁版嵁蹇収锛岀敤浜庢彁浜ゆ椂璺宠繃鏈彉鏇寸殑淇濆瓨璇锋眰
-const isEditable = computed(() =>
- // 鏄惁涓虹紪杈戞ā寮忥紙鍙繚瀛橈級
- ['create', 'update'].includes(formType.value),
-);
-const canSubmit = computed(
- () =>
- // 鏄惁鍙彁浜�
- formType.value === 'update' &&
- formData.value?.status === MesWmArrivalNoticeStatusEnum.PREPARE,
-);
-const getTitle = computed(() => {
- if (formType.value === 'detail') {
- return $t('ui.actionTitle.view', ['鍒拌揣閫氱煡鍗�']);
- }
- return formType.value === 'update'
- ? $t('ui.actionTitle.edit', ['鍒拌揣閫氱煡鍗�'])
- : $t('ui.actionTitle.create', ['鍒拌揣閫氱煡鍗�']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 110,
- },
- layout: 'horizontal',
- schema: [],
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-/** 鎻愪氦閫氱煡鍗曪細琛ㄥ崟鏈変慨鏀规椂鍏堜繚瀛橈紝鍐嶈皟鐢ㄦ彁浜ゆ帴鍙� */
-async function handleSubmit() {
- const { valid } = await formApi.validate();
- if (!valid || !formData.value?.id) {
- return;
- }
- modalApi.lock();
- try {
- const current = JSON.stringify(await formApi.getValues());
- if (current !== originalSnapshot.value) {
- const data =
- (await formApi.getValues()) as MesWmArrivalNoticeApi.ArrivalNotice;
- await updateArrivalNotice({ ...formData.value, ...data });
- originalSnapshot.value = current;
- }
- await submitArrivalNotice(formData.value.id);
- message.success('鎻愪氦鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- if (!isEditable.value) {
- await modalApi.close();
- return;
- }
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data =
- (await formApi.getValues()) as MesWmArrivalNoticeApi.ArrivalNotice;
- try {
- if (formData.value?.id) {
- await updateArrivalNotice({ ...formData.value, ...data });
- formData.value = { ...formData.value, ...data };
- } else {
- const id = await createArrivalNotice(data);
- formData.value = {
- ...data,
- id,
- status: MesWmArrivalNoticeStatusEnum.PREPARE,
- };
- await formApi.setFieldValue('id', id);
- await formApi.setFieldValue('status', formData.value.status);
- formType.value = 'update';
- }
- originalSnapshot.value = JSON.stringify(await formApi.getValues());
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- originalSnapshot.value = '';
- return;
- }
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{ formType: FormType; id?: number }>();
- formType.value = data.formType;
- formApi.setState({ schema: useFormSchema(formType.value, formApi) });
- formApi.setDisabled(!isEditable.value);
- modalApi.setState({ showConfirmButton: isEditable.value });
- if (data?.id) {
- modalApi.lock();
- try {
- formData.value = await getArrivalNotice(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- }
- originalSnapshot.value = JSON.stringify(await formApi.getValues());
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- <!-- 闈炴柊寤烘ā寮忓睍绀虹墿鏂欎俊鎭� -->
- <template v-if="formData?.id">
- <Divider>鐗╂枡淇℃伅</Divider>
- <div class="mx-4">
- <LineList :form-type="formType" :notice-id="formData.id" />
- </div>
- </template>
- <template #prepend-footer>
- <div class="flex flex-auto items-center gap-2">
- <Popconfirm
- v-if="canSubmit"
- title="纭鎻愪氦璇ュ埌璐ч�氱煡鍗曪紵銆愭彁浜ゅ悗灏嗕笉鑳戒慨鏀广��"
- @confirm="handleSubmit"
- >
- <Button type="primary">鎻愪氦</Button>
- </Popconfirm>
- </div>
- </template>
- </Modal>
-</template>
diff --git a/src/views/arrivalnotice/modules/line-form.vue b/src/views/arrivalnotice/modules/line-form.vue
deleted file mode 100644
index cf9e4dd..0000000
--- a/src/views/arrivalnotice/modules/line-form.vue
+++ /dev/null
@@ -1,94 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmArrivalNoticeLineApi } from '#/api/mes/wm/arrivalnotice/line';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createArrivalNoticeLine,
- getArrivalNoticeLine,
- updateArrivalNoticeLine,
-} from '#/api/mes/wm/arrivalnotice/line';
-import { $t } from '#/locales';
-
-import { useLineFormSchema } from '../data';
-
-const emit = defineEmits(['success']);
-const formData = ref<MesWmArrivalNoticeLineApi.ArrivalNoticeLine>();
-const noticeId = ref<number>(); // 鎵�灞為�氱煡鍗曠紪鍙�
-
-const getTitle = computed(() => {
- return formData.value?.id
- ? $t('ui.actionTitle.edit', ['鍒拌揣閫氱煡鍗曡'])
- : $t('ui.actionTitle.create', ['鍒拌揣閫氱煡鍗曡']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 90,
- },
- layout: 'horizontal',
- schema: useLineFormSchema(),
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data =
- (await formApi.getValues()) as MesWmArrivalNoticeLineApi.ArrivalNoticeLine;
- data.noticeId = noticeId.value;
- try {
- await (formData.value?.id
- ? updateArrivalNoticeLine({ ...data, id: formData.value.id })
- : createArrivalNoticeLine(data));
- // 鍏抽棴骞舵彁绀�
- await modalApi.close();
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- return;
- }
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{ id?: number; noticeId: number }>();
- noticeId.value = data.noticeId;
- if (!data.id) {
- return;
- }
- modalApi.lock();
- try {
- formData.value = await getArrivalNoticeLine(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- </Modal>
-</template>
diff --git a/src/views/arrivalnotice/modules/line-list.vue b/src/views/arrivalnotice/modules/line-list.vue
deleted file mode 100644
index a48316f..0000000
--- a/src/views/arrivalnotice/modules/line-list.vue
+++ /dev/null
@@ -1,140 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmArrivalNoticeLineApi } from '#/api/mes/wm/arrivalnotice/line';
-
-import { computed } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import {
- deleteArrivalNoticeLine,
- getArrivalNoticeLinePage,
-} from '#/api/mes/wm/arrivalnotice/line';
-import { $t } from '#/locales';
-
-import { useLineGridColumns } from '../data';
-import LineForm from './line-form.vue';
-
-const props = defineProps<{
- formType: FormType;
- noticeId: number;
-}>();
-
-const isEditable = computed(() =>
- // 鏄惁鍙紪杈戞槑缁嗚
- ['create', 'update'].includes(props.formType),
-);
-
-const [LineFormModal, lineFormModalApi] = useVbenModal({
- connectedComponent: LineForm,
- destroyOnClose: true,
-});
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- gridApi.query();
-}
-
-/** 娣诲姞鐗╂枡 */
-function handleCreate() {
- lineFormModalApi.setData({ noticeId: props.noticeId }).open();
-}
-
-/** 缂栬緫鐗╂枡 */
-function handleEdit(row: MesWmArrivalNoticeLineApi.ArrivalNoticeLine) {
- lineFormModalApi.setData({ id: row.id, noticeId: props.noticeId }).open();
-}
-
-/** 鍒犻櫎鐗╂枡 */
-async function handleDelete(row: MesWmArrivalNoticeLineApi.ArrivalNoticeLine) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.itemName]),
- duration: 0,
- });
- try {
- await deleteArrivalNoticeLine(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.itemName]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- gridOptions: {
- columns: useLineGridColumns(isEditable.value),
- height: 400,
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }) => {
- if (!props.noticeId) {
- return { list: [], total: 0 };
- }
- return await getArrivalNoticeLinePage({
- noticeId: props.noticeId,
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- },
- } as VxeTableGridOptions<MesWmArrivalNoticeLineApi.ArrivalNoticeLine>,
-});
-</script>
-
-<template>
- <div>
- <LineFormModal @success="handleRefresh" />
- <Grid table-title="鐗╂枡淇℃伅">
- <template v-if="isEditable" #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: '娣诲姞鐗╂枡',
- type: 'primary',
- icon: ACTION_ICON.ADD,
- onClick: handleCreate,
- },
- ]"
- />
- </template>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- ifShow: isEditable,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- ifShow: isEditable,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.itemName]),
- confirm: handleDelete.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </div>
-</template>
diff --git a/src/views/barcode/components/barcode.vue b/src/views/barcode/components/barcode.vue
deleted file mode 100644
index 4da3975..0000000
--- a/src/views/barcode/components/barcode.vue
+++ /dev/null
@@ -1,51 +0,0 @@
-<script lang="ts" setup>
-import type { BarcodeFormat } from '@vben/common-ui';
-
-import { computed, ref } from 'vue';
-
-import { BarcodeFormatEnum, Barcode as CommonBarcode } from '@vben/common-ui';
-
-defineOptions({ name: 'MesWmBarcode' });
-
-const props = withDefaults(
- defineProps<{
- content?: string;
- displayValue?: boolean;
- format?: number;
- height?: number;
- width?: number;
- }>(),
- {
- content: '',
- displayValue: true,
- format: BarcodeFormatEnum.QR_CODE,
- height: 100,
- width: 200,
- },
-);
-
-const emit = defineEmits<{ done: [value: string] }>();
-
-const barcodeRef = ref<InstanceType<typeof CommonBarcode>>();
-const commonFormat = computed<BarcodeFormat>(
- () => (props.format || BarcodeFormatEnum.QR_CODE) as BarcodeFormat,
-);
-
-function getImageBase64() {
- return barcodeRef.value?.getImageBase64() || '';
-}
-
-defineExpose({ getImageBase64 });
-</script>
-
-<template>
- <CommonBarcode
- ref="barcodeRef"
- :content="content"
- :display-value="displayValue"
- :format="commonFormat"
- :height="height"
- :width="width"
- @done="emit('done', $event)"
- />
-</template>
diff --git a/src/views/barcode/components/detail.vue b/src/views/barcode/components/detail.vue
deleted file mode 100644
index fec947d..0000000
--- a/src/views/barcode/components/detail.vue
+++ /dev/null
@@ -1,169 +0,0 @@
-<script lang="ts" setup>
-import type Barcode from './barcode.vue';
-
-import type { MesWmBarcodeApi } from '#/api/mes/wm/barcode';
-
-import { ref } from 'vue';
-
-import { Button, Empty, message, Modal, Tooltip } from 'ant-design-vue';
-
-import { createBarcode, getBarcodeByBusiness } from '#/api/mes/wm/barcode';
-import { useDescription } from '#/components/description';
-
-import { useBarcodeDetailSchema } from '../data';
-import MesWmBarcode from './barcode.vue';
-
-defineOptions({ name: 'MesWmBarcodeDetail' });
-
-const open = ref(false);
-const barcodeRef = ref<InstanceType<typeof Barcode>>();
-const barcodeData = ref<Partial<MesWmBarcodeApi.Barcode>>({});
-
-const [Descriptions] = useDescription({
- bordered: true,
- column: 1,
- schema: useBarcodeDetailSchema(),
- useCard: false,
-});
-
-function openModal(row: Partial<MesWmBarcodeApi.Barcode>) {
- open.value = true;
- barcodeData.value = { ...row };
-}
-
-async function openByBusiness(
- bizId: number,
- bizType: number,
- bizCode?: string,
- bizName?: string,
-) {
- open.value = true;
- try {
- const data = await getBarcodeByBusiness(bizType, bizId);
- barcodeData.value = data || {
- bizCode,
- bizId,
- bizName,
- bizType,
- content: '',
- };
- if (!data) {
- message.warning('鏈壘鍒板搴旀潯鐮佹暟鎹�');
- }
- } catch {
- barcodeData.value = { bizCode, bizId, bizName, bizType, content: '' };
- message.error('鍔犺浇鏉$爜鏁版嵁澶辫触');
- }
-}
-
-defineExpose({ open: openModal, openByBusiness });
-
-function escapeHtml(value: string) {
- return value
- .replaceAll('&', '&')
- .replaceAll('<', '<')
- .replaceAll('>', '>');
-}
-
-function handlePrint() {
- const base64 = barcodeRef.value?.getImageBase64();
- if (!base64) {
- message.warning('鏉$爜鐢熸垚澶辫触锛屾棤娉曟墦鍗�');
- return;
- }
- const printWindow = window.open('', '_blank');
- if (!printWindow) {
- message.error('鏃犳硶鎵撳紑鎵撳嵃绐楀彛锛岃妫�鏌ユ祻瑙堝櫒璁剧疆');
- return;
- }
- printWindow.document.write(`<!DOCTYPE html>
-<html><head><meta charset="UTF-8"><title>鎵撳嵃鏉$爜</title>
-<style>*{margin:0;padding:0}body{font-family:Arial,sans-serif;padding:20px}.print-container{text-align:center}.barcode-img{max-width:100%;margin:20px 0}.info{margin-top:20px;text-align:left;font-size:12px}.info p{margin:5px 0}@media print{body{padding:0}.print-container{padding:20px}}</style>
-</head><body><div class="print-container">
-<img src="${base64}" class="barcode-img" alt="鏉$爜" />
-<div class="info">
-<p><strong>涓氬姟缂栫爜:</strong> ${escapeHtml(barcodeData.value.bizCode || '')}</p>
-<p><strong>涓氬姟鍚嶇О:</strong> ${escapeHtml(barcodeData.value.bizName || '')}</p>
-<p><strong>鏉$爜鍐呭:</strong> ${escapeHtml(barcodeData.value.content || '')}</p>
-</div></div></body></html>`);
- printWindow.document.close();
- printWindow.addEventListener('load', () => {
- setTimeout(() => printWindow.print(), 500);
- });
-}
-
-function handleDownload() {
- const base64 = barcodeRef.value?.getImageBase64();
- if (!base64) {
- message.warning('鏉$爜鐢熸垚澶辫触锛屾棤娉曚笅杞�');
- return;
- }
- const link = document.createElement('a');
- link.href = base64;
- link.download = `barcode_${barcodeData.value.bizCode || 'unknown'}_${Date.now()}.png`;
- link.click();
- message.success('涓嬭浇鎴愬姛');
-}
-
-async function handleGenerate() {
- const { bizCode, bizId, bizName, bizType } = barcodeData.value;
- if (!bizType || !bizId) {
- message.warning('缂哄皯涓氬姟绫诲瀷鎴栦笟鍔$紪鍙凤紝鏃犳硶鐢熸垚鏉$爜');
- return;
- }
- await createBarcode({
- bizCode: bizCode || '',
- bizId,
- bizName: bizName || '',
- bizType,
- });
- message.success('鏉$爜鐢熸垚鎴愬姛');
- const data = await getBarcodeByBusiness(bizType, bizId);
- if (data) {
- barcodeData.value = { ...data };
- }
-}
-</script>
-
-<template>
- <Modal v-model:open="open" title="鏌ョ湅鏉$爜" width="500px">
- <div>
- <div
- class="mb-5 flex min-h-50 items-center justify-center rounded bg-gray-100 p-5"
- >
- <div
- v-if="barcodeData.content"
- class="flex items-center justify-center"
- >
- <MesWmBarcode
- ref="barcodeRef"
- :content="barcodeData.content"
- :format="barcodeData.format"
- :height="150"
- :width="400"
- />
- </div>
- <Empty v-else description="鏆傛棤鏉$爜鏁版嵁" />
- </div>
- <Descriptions :data="barcodeData">
- <template #content>
- <Tooltip :title="barcodeData.content">
- <span
- class="inline-block max-w-75 overflow-hidden text-ellipsis whitespace-nowrap"
- >
- {{ barcodeData.content }}
- </span>
- </Tooltip>
- </template>
- </Descriptions>
- </div>
- <template #footer>
- <Button v-if="!barcodeData.content" @click="handleGenerate">
- 鐢熸垚
- </Button>
- <Button type="primary" @click="handlePrint">鎵撳嵃</Button>
- <Button @click="handleDownload">涓嬭浇</Button>
- <Button @click="open = false">鍏抽棴</Button>
- </template>
- </Modal>
-</template>
diff --git a/src/views/barcode/components/index.ts b/src/views/barcode/components/index.ts
deleted file mode 100644
index 9bd45df..0000000
--- a/src/views/barcode/components/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export { default as Barcode } from './barcode.vue';
-export { default as BarcodeDetail } from './detail.vue';
-export { default as PrinterLabel } from './printer-label.vue';
diff --git a/src/views/barcode/components/printer-label.vue b/src/views/barcode/components/printer-label.vue
deleted file mode 100644
index 5221829..0000000
--- a/src/views/barcode/components/printer-label.vue
+++ /dev/null
@@ -1,30 +0,0 @@
-<script lang="ts" setup>
-import { Button, message } from 'ant-design-vue';
-
-defineOptions({ name: 'MesWmPrinterLabel' });
-
-withDefaults(
- defineProps<{
- bizCode?: string;
- bizId?: number;
- bizType?: string;
- labelText?: string;
- }>(),
- {
- bizCode: undefined,
- bizId: undefined,
- bizType: undefined,
- labelText: '鏍囩鎵撳嵃',
- },
-);
-
-function handlePrint() {
- message.warning('鏍囩鎵撳嵃鍔熻兘鏆傛湭瀹炵幇锛屾暚璇锋湡寰�');
-}
-</script>
-
-<template>
- <Button type="link" @click="handlePrint">
- {{ labelText }}
- </Button>
-</template>
diff --git a/src/views/barcode/config/data.ts b/src/views/barcode/config/data.ts
deleted file mode 100644
index 125ce1d..0000000
--- a/src/views/barcode/config/data.ts
+++ /dev/null
@@ -1,114 +0,0 @@
-import type { VbenFormSchema } from '#/adapter/form';
-
-import { h } from 'vue';
-
-import { CommonStatusEnum, DICT_TYPE } from '@vben/constants';
-import { getDictOptions } from '@vben/hooks';
-
-import { Button, message } from 'ant-design-vue';
-
-import { z } from '#/adapter/form';
-
-/** 琛ㄥ崟 */
-export function useFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'id',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'format',
- label: '鏉$爜鏍煎紡',
- component: 'Select',
- componentProps: {
- options: getDictOptions(DICT_TYPE.MES_WM_BARCODE_FORMAT, 'number'),
- placeholder: '璇烽�夋嫨鏉$爜鏍煎紡',
- },
- rules: 'required',
- },
- {
- fieldName: 'bizType',
- label: '涓氬姟绫诲瀷',
- component: 'Select',
- componentProps: {
- options: getDictOptions(DICT_TYPE.MES_WM_BARCODE_BIZ_TYPE, 'number'),
- placeholder: '璇烽�夋嫨涓氬姟绫诲瀷',
- },
- dependencies: {
- triggerFields: ['id'],
- componentProps: (values) => ({
- disabled: !!values.id, // 缂栬緫鏃朵笟鍔$被鍨嬩笉鍏佽鍙樻洿
- }),
- },
- rules: 'required',
- },
- {
- fieldName: 'contentFormat',
- label: '鍐呭鏍煎紡妯℃澘',
- component: 'Input',
- componentProps: {
- placeholder: '鏀寔{BUSINESSCODE}鍗犱綅绗︼紝濡傦細WH-{BUSINESSCODE}',
- },
- rules: 'required',
- },
- {
- fieldName: 'contentExample',
- label: '鍐呭鏍蜂緥',
- component: 'Input',
- componentProps: {
- placeholder: '濡傦細WH-WH001',
- },
- },
- {
- fieldName: 'autoGenerateFlag',
- label: '鑷姩鐢熸垚',
- component: 'Switch',
- componentProps: {
- checkedChildren: '鏄�',
- unCheckedChildren: '鍚�',
- },
- rules: z.boolean().default(true),
- },
- {
- fieldName: 'defaultTemplate',
- label: '榛樿鎵撳嵃妯℃澘',
- component: 'Input',
- componentProps: {
- placeholder: '璇烽�夋嫨鎵撳嵃妯℃澘',
- readonly: true,
- },
- // TODO @鑺嬭壙锛氬悗缁鎺� UReport 鎶ヨ〃閫夋嫨鍣紝瀹炵幇鎵撳嵃妯℃澘閫夋嫨鍔熻兘
- suffix: () =>
- h(
- Button,
- {
- onClick: () =>
- message.warning('鎵撳嵃妯℃澘閫夋嫨鍔熻兘鏆傛湭瀹炵幇锛屾暚璇锋湡寰�'),
- },
- { default: () => '璁剧疆' },
- ),
- },
- {
- fieldName: 'status',
- label: '鐘舵��',
- component: 'RadioGroup',
- componentProps: {
- options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'),
- },
- rules: z.number().default(CommonStatusEnum.ENABLE),
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 2,
- },
- },
- ];
-}
diff --git a/src/views/barcode/config/index.vue b/src/views/barcode/config/index.vue
deleted file mode 100644
index b6cc804..0000000
--- a/src/views/barcode/config/index.vue
+++ /dev/null
@@ -1,150 +0,0 @@
-<script lang="ts" setup>
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmBarcodeConfigApi } from '#/api/mes/wm/barcode/config';
-
-import { confirm, Page, useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import {
- deleteBarcodeConfig,
- getBarcodeConfigPage,
- updateBarcodeConfig,
-} from '#/api/mes/wm/barcode/config';
-import { $t } from '#/locales';
-
-import { useConfigGridColumns, useConfigGridFormSchema } from '../data';
-import ConfigForm from './modules/form.vue';
-
-const [FormModal, formModalApi] = useVbenModal({
- connectedComponent: ConfigForm,
- destroyOnClose: true,
-});
-
-/** 鑷姩鐢熸垚寮�鍏冲彉鏇� */
-async function handleAutoGenerateChange(
- row: MesWmBarcodeConfigApi.BarcodeConfig,
-): Promise<boolean> {
- const text = row.autoGenerateFlag ? '鍚敤' : '鍋滅敤';
- try {
- await confirm(`纭瑕�${text}鑷姩鐢熸垚鍚楋紵`);
- } catch {
- return false;
- }
- await updateBarcodeConfig(row);
- message.success(`${text}鎴愬姛`);
- return true;
-}
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- gridApi.query();
-}
-
-/** 鍒涘缓鏉$爜閰嶇疆 */
-function handleCreate() {
- formModalApi.setData(null).open();
-}
-
-/** 缂栬緫鏉$爜閰嶇疆 */
-function handleEdit(row: MesWmBarcodeConfigApi.BarcodeConfig) {
- formModalApi.setData(row).open();
-}
-
-/** 鍒犻櫎鏉$爜閰嶇疆 */
-async function handleDelete(row: MesWmBarcodeConfigApi.BarcodeConfig) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [
- row.contentFormat || `#${row.id}`,
- ]),
- duration: 0,
- });
- try {
- await deleteBarcodeConfig(row.id!);
- message.success(
- $t('ui.actionMessage.deleteSuccess', [row.contentFormat || `#${row.id}`]),
- );
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- formOptions: {
- schema: useConfigGridFormSchema(),
- },
- gridOptions: {
- columns: useConfigGridColumns(handleAutoGenerateChange),
- height: 'auto',
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }, formValues) => {
- return await getBarcodeConfigPage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- ...formValues,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- search: true,
- },
- } as VxeTableGridOptions<MesWmBarcodeConfigApi.BarcodeConfig>,
-});
-</script>
-
-<template>
- <Page auto-content-height><FormModal @success="handleRefresh" />
-
- <Grid table-title="鏉$爜閰嶇疆鍒楄〃">
- <template #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: $t('ui.actionTitle.create', ['鏉$爜閰嶇疆']),
- type: 'primary',
- icon: ACTION_ICON.ADD,
- auth: ['mes:wm-barcode-config:create'],
- onClick: handleCreate,
- },
- ]"
- />
- </template>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- auth: ['mes:wm-barcode-config:update'],
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- auth: ['mes:wm-barcode-config:delete'],
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [
- row.contentFormat || `#${row.id}`,
- ]),
- confirm: handleDelete.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </Page>
-</template>
diff --git a/src/views/barcode/config/modules/form.vue b/src/views/barcode/config/modules/form.vue
deleted file mode 100644
index fc1ff97..0000000
--- a/src/views/barcode/config/modules/form.vue
+++ /dev/null
@@ -1,89 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmBarcodeConfigApi } from '#/api/mes/wm/barcode/config';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createBarcodeConfig,
- getBarcodeConfig,
- updateBarcodeConfig,
-} from '#/api/mes/wm/barcode/config';
-import { $t } from '#/locales';
-
-import { useFormSchema } from '../data';
-
-const emit = defineEmits(['success']);
-const formData = ref<MesWmBarcodeConfigApi.BarcodeConfig>();
-const getTitle = computed(() => {
- return formData.value?.id
- ? $t('ui.actionTitle.edit', ['鏉$爜閰嶇疆'])
- : $t('ui.actionTitle.create', ['鏉$爜閰嶇疆']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-2',
- labelWidth: 130,
- },
- layout: 'horizontal',
- schema: useFormSchema(),
- showDefaultActions: false,
-});
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data =
- (await formApi.getValues()) as MesWmBarcodeConfigApi.BarcodeConfig;
- try {
- await (formData.value?.id
- ? updateBarcodeConfig(data)
- : createBarcodeConfig(data));
- // 鍏抽棴骞舵彁绀�
- await modalApi.close();
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- return;
- }
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<MesWmBarcodeConfigApi.BarcodeConfig>();
- if (!data || !data.id) {
- return;
- }
- modalApi.lock();
- try {
- formData.value = await getBarcodeConfig(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-2/5">
- <Form class="mx-4" />
- </Modal>
-</template>
diff --git a/src/views/barcode/data.ts b/src/views/barcode/data.ts
deleted file mode 100644
index dfd288c..0000000
--- a/src/views/barcode/data.ts
+++ /dev/null
@@ -1,735 +0,0 @@
-锘縤mport type { VbenFormApi, VbenFormSchema } from '#/adapter/form';
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmBarcodeApi } from '#/api/mes/wm/barcode';
-import type { MesWmBarcodeConfigApi } from '#/api/mes/wm/barcode/config';
-import type { DescriptionItemSchema } from '#/components/description';
-
-import { h, markRaw } from 'vue';
-
-import {
- BarcodeBizTypeEnum,
- CommonStatusEnum,
- DICT_TYPE,
- MesProWorkOrderStatusEnum,
-} from '@vben/constants';
-import { getDictOptions } from '@vben/hooks';
-import { formatDateTime } from '@vben/utils';
-
-import { z } from '#/adapter/form';
-import { generateBarcodeContent } from '#/api/mes/wm/barcode';
-import { DictTag } from '#/components/dict-tag';
-import { DvMachinerySelect } from '#/views/mes/dv/machinery/components';
-import { MdClientSelect } from '#/views/mes/md/client/components';
-import { MdItemSelect } from '#/views/mes/md/item/components';
-import { MdVendorSelect } from '#/views/mes/md/vendor/components';
-import {
- MdWorkshopSelect,
- MdWorkstationSelect,
-} from '#/views/mes/md/workstation/components';
-import { ProCardSelect } from '#/views/mes/pro/card/components';
-import { ProWorkOrderSelect } from '#/views/mes/pro/workorder/components';
-import { TmToolSelect } from '#/views/mes/tm/tool/components';
-import { WmBatchSelect } from '#/views/wls/batch/components';
-import { UserSelect } from '#/views/system/user/components';
-
-import { WmMaterialStockSelect } from '../materialstock/components';
-import { WmPackageSelect } from '#/views/wls/packages/components';
-import {
- WmWarehouseAreaSelect,
- WmWarehouseLocationSelect,
- WmWarehouseSelect,
-} from '../warehouse/components';
-
-/** 涓氬姟瀵硅薄閫変腑鍚庡洖濉笟鍔$紪鐮併�佷笟鍔″悕绉般�佹潯鐮佸唴瀹� */
-async function syncBizDetail(formApi: undefined | VbenFormApi, item: any) {
- if (!formApi) {
- return;
- }
- const values = await formApi.getValues();
- const bizType = values.bizType as number | undefined;
- if (!item) {
- await formApi.setValues({
- bizCode: undefined,
- bizName: undefined,
- content: undefined,
- });
- return;
- }
- let bizCode: string | undefined;
- let bizName: string | undefined;
- switch (bizType) {
- case BarcodeBizTypeEnum.BATCH: {
- bizCode = item.code;
- bizName = item.itemName || item.code;
- break;
- }
- case BarcodeBizTypeEnum.PACKAGE: {
- bizCode = item.code;
- bizName = item.clientName || item.code;
- break;
- }
- case BarcodeBizTypeEnum.PROCARD: {
- bizCode = item.code;
- bizName = item.workOrderName || item.code;
- break;
- }
- case BarcodeBizTypeEnum.STOCK: {
- bizCode = item.itemCode;
- bizName = item.itemName;
- break;
- }
- default: {
- bizCode = item.code || item.username;
- bizName = item.name || item.nickname;
- }
- }
- // 鍏堝洖濉笟鍔$紪鐮併�佸悕绉板苟娓呯┖鏃ф潯鐮佸唴瀹�
- await formApi.setValues({ bizCode, bizName, content: undefined });
- // 鍐嶆牴鎹笟鍔$被鍨� + 涓氬姟缂栫爜鐢熸垚鏉$爜鍐呭
- if (bizType && bizCode) {
- const content = await generateBarcodeContent(bizType, bizCode);
- await formApi.setFieldValue('content', content);
- }
-}
-
-/** 鏂板/淇敼鏉$爜鐨勮〃鍗� */
-export function useFormSchema(formApi?: VbenFormApi): VbenFormSchema[] {
- return [
- {
- fieldName: 'bizType',
- label: '涓氬姟绫诲瀷',
- component: 'Select',
- componentProps: {
- // 涓氬姟绫诲瀷鍙樻洿鏃舵竻绌轰笟鍔″瓧娈�
- onChange: () =>
- formApi?.setValues({
- bizId: undefined,
- bizCode: undefined,
- bizName: undefined,
- content: undefined,
- locationWarehouseId: undefined,
- areaWarehouseId: undefined,
- areaLocationId: undefined,
- }),
- options: getDictOptions(DICT_TYPE.MES_WM_BARCODE_BIZ_TYPE, 'number'),
- placeholder: '璇烽�夋嫨涓氬姟绫诲瀷',
- },
- rules: 'required',
- },
- // ==================== 涓氬姟瀵硅薄閫夋嫨鍣紙鎸� bizType 鍒囨崲锛� ====================
- {
- fieldName: 'bizId',
- label: '浠撳簱',
- component: markRaw(WmWarehouseSelect),
- componentProps: {
- onChange: (item: any) => syncBizDetail(formApi, item),
- },
- dependencies: {
- triggerFields: ['bizType'],
- show: (values) => values.bizType === BarcodeBizTypeEnum.WAREHOUSE,
- },
- rules: 'required',
- },
- {
- fieldName: 'locationWarehouseId',
- label: '搴撳尯路浠撳簱',
- component: markRaw(WmWarehouseSelect),
- componentProps: {
- onChange: () =>
- formApi?.setValues({
- bizId: undefined,
- bizCode: undefined,
- bizName: undefined,
- content: undefined,
- }),
- placeholder: '璇烽�夋嫨浠撳簱',
- },
- dependencies: {
- triggerFields: ['bizType'],
- show: (values) => values.bizType === BarcodeBizTypeEnum.LOCATION,
- },
- },
- {
- fieldName: 'bizId',
- label: '搴撳尯',
- component: markRaw(WmWarehouseLocationSelect),
- dependencies: {
- triggerFields: ['bizType', 'locationWarehouseId'],
- show: (values) => values.bizType === BarcodeBizTypeEnum.LOCATION,
- componentProps: (values) => ({
- onChange: (item: any) => syncBizDetail(formApi, item),
- placeholder: '璇烽�夋嫨搴撳尯',
- warehouseId: values.locationWarehouseId,
- }),
- },
- rules: 'required',
- },
- {
- fieldName: 'areaWarehouseId',
- label: '搴撲綅路浠撳簱',
- component: markRaw(WmWarehouseSelect),
- componentProps: {
- onChange: () =>
- formApi?.setValues({
- areaLocationId: undefined,
- bizId: undefined,
- bizCode: undefined,
- bizName: undefined,
- content: undefined,
- }),
- placeholder: '璇烽�夋嫨浠撳簱',
- },
- dependencies: {
- triggerFields: ['bizType'],
- show: (values) => values.bizType === BarcodeBizTypeEnum.AREA,
- },
- },
- {
- fieldName: 'areaLocationId',
- label: '搴撲綅路搴撳尯',
- component: markRaw(WmWarehouseLocationSelect),
- dependencies: {
- triggerFields: ['bizType', 'areaWarehouseId'],
- show: (values) => values.bizType === BarcodeBizTypeEnum.AREA,
- componentProps: (values) => ({
- onChange: () =>
- formApi?.setValues({
- bizId: undefined,
- bizCode: undefined,
- bizName: undefined,
- content: undefined,
- }),
- placeholder: '璇烽�夋嫨搴撳尯',
- warehouseId: values.areaWarehouseId,
- }),
- },
- },
- {
- fieldName: 'bizId',
- label: '搴撲綅',
- component: markRaw(WmWarehouseAreaSelect),
- dependencies: {
- triggerFields: ['bizType', 'areaLocationId'],
- show: (values) => values.bizType === BarcodeBizTypeEnum.AREA,
- componentProps: (values) => ({
- locationId: values.areaLocationId,
- onChange: (item: any) => syncBizDetail(formApi, item),
- placeholder: '璇烽�夋嫨搴撲綅',
- }),
- },
- rules: 'required',
- },
- {
- fieldName: 'bizId',
- label: '璁㈠崟',
- component: markRaw(ProWorkOrderSelect),
- componentProps: {
- status: MesProWorkOrderStatusEnum.CONFIRMED,
- onChange: (item: any) => syncBizDetail(formApi, item),
- },
- dependencies: {
- triggerFields: ['bizType'],
- show: (values) => values.bizType === BarcodeBizTypeEnum.WORKORDER,
- },
- rules: 'required',
- },
- {
- fieldName: 'bizId',
- label: '璁惧',
- component: markRaw(DvMachinerySelect),
- componentProps: {
- onChange: (item: any) => syncBizDetail(formApi, item),
- },
- dependencies: {
- triggerFields: ['bizType'],
- show: (values) => values.bizType === BarcodeBizTypeEnum.MACHINERY,
- },
- rules: 'required',
- },
- {
- fieldName: 'bizId',
- label: '浜у搧鐗╂枡',
- component: markRaw(MdItemSelect),
- componentProps: {
- onChange: (item: any) => syncBizDetail(formApi, item),
- },
- dependencies: {
- triggerFields: ['bizType'],
- show: (values) => values.bizType === BarcodeBizTypeEnum.ITEM,
- },
- rules: 'required',
- },
- {
- fieldName: 'bizId',
- label: '渚涘簲鍟�',
- component: markRaw(MdVendorSelect),
- componentProps: {
- onChange: (item: any) => syncBizDetail(formApi, item),
- },
- dependencies: {
- triggerFields: ['bizType'],
- show: (values) => values.bizType === BarcodeBizTypeEnum.VENDOR,
- },
- rules: 'required',
- },
- {
- fieldName: 'bizId',
- label: '宸ヤ綔绔�',
- component: markRaw(MdWorkstationSelect),
- componentProps: {
- onChange: (item: any) => syncBizDetail(formApi, item),
- },
- dependencies: {
- triggerFields: ['bizType'],
- show: (values) => values.bizType === BarcodeBizTypeEnum.WORKSTATION,
- },
- rules: 'required',
- },
- {
- fieldName: 'bizId',
- label: '杞﹂棿',
- component: markRaw(MdWorkshopSelect),
- componentProps: {
- onChange: (item: any) => syncBizDetail(formApi, item),
- },
- dependencies: {
- triggerFields: ['bizType'],
- show: (values) => values.bizType === BarcodeBizTypeEnum.WORKSHOP,
- },
- rules: 'required',
- },
- {
- fieldName: 'bizId',
- label: '瀹㈡埛',
- component: markRaw(MdClientSelect),
- componentProps: {
- onChange: (item: any) => syncBizDetail(formApi, item),
- },
- dependencies: {
- triggerFields: ['bizType'],
- show: (values) => values.bizType === BarcodeBizTypeEnum.CLIENT,
- },
- rules: 'required',
- },
- {
- fieldName: 'bizId',
- label: '宸ュ叿',
- component: markRaw(TmToolSelect),
- componentProps: {
- onChange: (item: any) => syncBizDetail(formApi, item),
- },
- dependencies: {
- triggerFields: ['bizType'],
- show: (values) => values.bizType === BarcodeBizTypeEnum.TOOL,
- },
- rules: 'required',
- },
- {
- fieldName: 'bizId',
- label: '搴撳瓨',
- component: markRaw(WmMaterialStockSelect),
- componentProps: {
- onChange: (item: any) => syncBizDetail(formApi, item),
- },
- dependencies: {
- triggerFields: ['bizType'],
- show: (values) => values.bizType === BarcodeBizTypeEnum.STOCK,
- },
- rules: 'required',
- },
- {
- fieldName: 'bizId',
- label: '瑁呯鍗�',
- component: markRaw(WmPackageSelect),
- componentProps: {
- childableOnly: true,
- onChange: (item: any) => syncBizDetail(formApi, item),
- },
- dependencies: {
- triggerFields: ['bizType'],
- show: (values) => values.bizType === BarcodeBizTypeEnum.PACKAGE,
- },
- rules: 'required',
- },
- {
- fieldName: 'bizId',
- label: '鎵规',
- component: markRaw(WmBatchSelect),
- componentProps: {
- onChange: (item: any) => syncBizDetail(formApi, item),
- },
- dependencies: {
- triggerFields: ['bizType'],
- show: (values) => values.bizType === BarcodeBizTypeEnum.BATCH,
- },
- rules: 'required',
- },
- {
- fieldName: 'bizId',
- label: '娴佽浆鍗�',
- component: markRaw(ProCardSelect),
- componentProps: {
- onChange: (item: any) => syncBizDetail(formApi, item),
- },
- dependencies: {
- triggerFields: ['bizType'],
- show: (values) => values.bizType === BarcodeBizTypeEnum.PROCARD,
- },
- rules: 'required',
- },
- {
- fieldName: 'bizId',
- label: '浜哄憳',
- component: markRaw(UserSelect),
- componentProps: {
- onChange: (item: any) => syncBizDetail(formApi, item),
- },
- dependencies: {
- triggerFields: ['bizType'],
- show: (values) => values.bizType === BarcodeBizTypeEnum.USER,
- },
- rules: 'required',
- },
- {
- fieldName: 'bizId',
- label: '涓氬姟缂栧彿',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 1,
- placeholder: '璇疯緭鍏ヤ笟鍔$紪鍙�',
- },
- dependencies: {
- triggerFields: ['bizType'],
- show: (values) =>
- values.bizType !== undefined &&
- ![
- BarcodeBizTypeEnum.AREA,
- BarcodeBizTypeEnum.BATCH,
- BarcodeBizTypeEnum.CLIENT,
- BarcodeBizTypeEnum.ITEM,
- BarcodeBizTypeEnum.LOCATION,
- BarcodeBizTypeEnum.MACHINERY,
- BarcodeBizTypeEnum.PACKAGE,
- BarcodeBizTypeEnum.PROCARD,
- BarcodeBizTypeEnum.STOCK,
- BarcodeBizTypeEnum.TOOL,
- BarcodeBizTypeEnum.USER,
- BarcodeBizTypeEnum.VENDOR,
- BarcodeBizTypeEnum.WAREHOUSE,
- BarcodeBizTypeEnum.WORKORDER,
- BarcodeBizTypeEnum.WORKSHOP,
- BarcodeBizTypeEnum.WORKSTATION,
- ].includes(values.bizType),
- },
- },
- {
- fieldName: 'bizCode',
- label: '涓氬姟缂栫爜',
- component: 'Input',
- componentProps: {
- disabled: true,
- placeholder: '鑷姩濉厖',
- },
- rules: 'required',
- },
- {
- fieldName: 'bizName',
- label: '涓氬姟鍚嶇О',
- component: 'Input',
- componentProps: {
- disabled: true,
- placeholder: '鑷姩濉厖',
- },
- rules: 'required',
- },
- {
- fieldName: 'content',
- label: '鏉$爜鍐呭',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ユ潯鐮佸唴瀹规垨鑷姩鐢熸垚',
- },
- rules: 'required',
- },
- {
- fieldName: 'status',
- label: '鐘舵��',
- component: 'RadioGroup',
- componentProps: {
- options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'),
- },
- rules: z.number().default(CommonStatusEnum.ENABLE),
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 2,
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勬悳绱㈣〃鍗� */
-export function useGridFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'bizType',
- label: '涓氬姟绫诲瀷',
- component: 'Select',
- componentProps: {
- allowClear: true,
- options: getDictOptions(DICT_TYPE.MES_WM_BARCODE_BIZ_TYPE, 'number'),
- placeholder: '璇烽�夋嫨涓氬姟绫诲瀷',
- },
- },
- {
- fieldName: 'bizCode',
- label: '涓氬姟缂栫爜',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ヤ笟鍔$紪鐮�',
- },
- },
- {
- fieldName: 'bizName',
- label: '涓氬姟鍚嶇О',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ヤ笟鍔″悕绉�',
- },
- },
- {
- fieldName: 'content',
- label: '鏉$爜鍐呭',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ユ潯鐮佸唴瀹�',
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勫瓧娈� */
-export function useGridColumns(): VxeTableGridOptions<MesWmBarcodeApi.Barcode>['columns'] {
- return [
- {
- type: 'checkbox',
- width: 50,
- },
- {
- field: 'content',
- title: '鏉$爜',
- width: 180,
- slots: { default: 'barcode' },
- },
- {
- field: 'format',
- title: '鏉$爜鏍煎紡',
- width: 110,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_BARCODE_FORMAT },
- },
- },
- {
- field: 'bizType',
- title: '涓氬姟绫诲瀷',
- width: 110,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_BARCODE_BIZ_TYPE },
- },
- },
- {
- field: 'content',
- title: '鏉$爜鍐呭',
- minWidth: 160,
- },
- {
- field: 'bizCode',
- title: '涓氬姟缂栫爜',
- width: 130,
- },
- {
- field: 'bizName',
- title: '涓氬姟鍚嶇О',
- minWidth: 140,
- },
- {
- field: 'status',
- title: '鐘舵��',
- width: 90,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.COMMON_STATUS },
- },
- },
- {
- title: '鎿嶄綔',
- width: 200,
- fixed: 'right',
- slots: { default: 'actions' },
- },
- ];
-}
-
-/** 閰嶇疆鍒楄〃鐨勬悳绱㈣〃鍗� */
-export function useConfigGridFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'format',
- label: '鏉$爜鏍煎紡',
- component: 'Select',
- componentProps: {
- allowClear: true,
- options: getDictOptions(DICT_TYPE.MES_WM_BARCODE_FORMAT, 'number'),
- placeholder: '璇烽�夋嫨鏉$爜鏍煎紡',
- },
- },
- {
- fieldName: 'bizType',
- label: '涓氬姟绫诲瀷',
- component: 'Select',
- componentProps: {
- allowClear: true,
- options: getDictOptions(DICT_TYPE.MES_WM_BARCODE_BIZ_TYPE, 'number'),
- placeholder: '璇烽�夋嫨涓氬姟绫诲瀷',
- },
- },
- ];
-}
-
-/** 閰嶇疆鍒楄〃鐨勫瓧娈� */
-export function useConfigGridColumns(
- onAutoGenerateChange: (
- row: MesWmBarcodeConfigApi.BarcodeConfig,
- ) => Promise<boolean>,
-): VxeTableGridOptions<MesWmBarcodeConfigApi.BarcodeConfig>['columns'] {
- return [
- {
- field: 'id',
- title: '缂栧彿',
- width: 100,
- },
- {
- field: 'format',
- title: '鏉$爜鏍煎紡',
- width: 110,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_BARCODE_FORMAT },
- },
- },
- {
- field: 'bizType',
- title: '涓氬姟绫诲瀷',
- width: 110,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_BARCODE_BIZ_TYPE },
- },
- },
- {
- field: 'contentFormat',
- title: '鍐呭鏍煎紡',
- minWidth: 160,
- },
- {
- field: 'contentExample',
- title: '鍐呭鏍蜂緥',
- minWidth: 160,
- },
- {
- field: 'defaultTemplate',
- title: '榛樿鎵撳嵃妯℃澘',
- minWidth: 140,
- },
- {
- field: 'autoGenerateFlag',
- title: '鑷姩鐢熸垚',
- width: 100,
- cellRender: {
- name: 'CellSwitch',
- attrs: { beforeChange: onAutoGenerateChange },
- },
- },
- {
- field: 'status',
- title: '鐘舵��',
- width: 90,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.COMMON_STATUS },
- },
- },
- {
- field: 'createTime',
- title: '鍒涘缓鏃堕棿',
- width: 180,
- formatter: 'formatDateTime',
- },
- {
- title: '鎿嶄綔',
- width: 160,
- fixed: 'right',
- slots: { default: 'actions' },
- },
- ];
-}
-
-/** 鏉$爜璇︽儏鐨勬弿杩板瓧娈� */
-export function useBarcodeDetailSchema(): DescriptionItemSchema[] {
- return [
- {
- field: 'format',
- label: '鏉$爜鏍煎紡',
- render: (value) =>
- value === null
- ? '-'
- : h(DictTag, { type: DICT_TYPE.MES_WM_BARCODE_FORMAT, value }),
- },
- {
- field: 'bizType',
- label: '涓氬姟绫诲瀷',
- render: (value) =>
- value === null
- ? '-'
- : h(DictTag, { type: DICT_TYPE.MES_WM_BARCODE_BIZ_TYPE, value }),
- },
- {
- field: 'content',
- label: '鏉$爜鍐呭',
- slot: 'content',
- },
- {
- field: 'bizCode',
- label: '涓氬姟缂栫爜',
- render: (value) => value || '-',
- },
- {
- field: 'bizName',
- label: '涓氬姟鍚嶇О',
- render: (value) => value || '-',
- },
- {
- field: 'status',
- label: '鐘舵��',
- render: (value) =>
- value === null
- ? '-'
- : h(DictTag, { type: DICT_TYPE.COMMON_STATUS, value }),
- },
- {
- field: 'createTime',
- label: '鍒涘缓鏃堕棿',
- render: (value) => formatDateTime(value) || '-',
- },
- ];
-}
diff --git a/src/views/barcode/index.vue b/src/views/barcode/index.vue
deleted file mode 100644
index 7c11046..0000000
--- a/src/views/barcode/index.vue
+++ /dev/null
@@ -1,234 +0,0 @@
-<script lang="ts" setup>
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmBarcodeApi } from '#/api/mes/wm/barcode';
-
-import { ref } from 'vue';
-import { useRouter } from 'vue-router';
-
-import { Page, useVbenModal } from '@vben/common-ui';
-import { downloadFileFromBlobPart } from '@vben/utils';
-
-import { message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import {
- deleteBarcode,
- exportBarcode,
- getBarcodePage,
-} from '#/api/mes/wm/barcode';
-import { $t } from '#/locales';
-
-import { Barcode, BarcodeDetail } from './components';
-import { useGridColumns, useGridFormSchema } from './data';
-import Form from './modules/form.vue';
-
-const router = useRouter();
-
-const [FormModal, formModalApi] = useVbenModal({
- connectedComponent: Form,
- destroyOnClose: true,
-});
-
-const barcodeDetailRef = ref<InstanceType<typeof BarcodeDetail>>();
-
-const checkedIds = ref<number[]>([]);
-function handleRowCheckboxChange({
- records,
-}: {
- records: MesWmBarcodeApi.Barcode[];
-}) {
- checkedIds.value = records.map((item) => item.id!);
-}
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- gridApi.query();
-}
-
-/** 鍒涘缓鏉$爜 */
-function handleCreate() {
- formModalApi.setData(null).open();
-}
-
-/** 缂栬緫鏉$爜 */
-function handleEdit(row: MesWmBarcodeApi.Barcode) {
- formModalApi.setData(row).open();
-}
-
-/** 鍒犻櫎鏉$爜 */
-async function handleDelete(row: MesWmBarcodeApi.Barcode) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [
- row.bizName || row.bizCode || '',
- ]),
- duration: 0,
- });
- try {
- await deleteBarcode(row.id!);
- message.success(
- $t('ui.actionMessage.deleteSuccess', [row.bizName || row.bizCode || '']),
- );
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-/** 鎵归噺鍒犻櫎鏉$爜 */
-async function handleDeleteBatch() {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [`${checkedIds.value.length} 鏉]),
- duration: 0,
- });
- try {
- await Promise.all(checkedIds.value.map((id) => deleteBarcode(id)));
- message.success($t('ui.actionMessage.deleteSuccess', ['']));
- checkedIds.value = [];
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-/** 鏌ョ湅鏉$爜 */
-function handleView(row: MesWmBarcodeApi.Barcode) {
- barcodeDetailRef.value?.open(row);
-}
-
-/** 璺宠浆鏉$爜閰嶇疆 */
-function handleConfig() {
- router.push({ name: 'MesWmBarcodeConfig' });
-}
-
-/** 瀵煎嚭琛ㄦ牸 */
-async function handleExport() {
- const data = await exportBarcode(await gridApi.formApi.getValues());
- downloadFileFromBlobPart({ fileName: '鏉$爜娓呭崟.xls', source: data });
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- formOptions: {
- schema: useGridFormSchema(),
- },
- gridOptions: {
- columns: useGridColumns(),
- height: 'auto',
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }, formValues) => {
- return await getBarcodePage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- ...formValues,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- height: 80,
- },
- toolbarConfig: {
- refresh: true,
- search: true,
- },
- } as VxeTableGridOptions<MesWmBarcodeApi.Barcode>,
- gridEvents: {
- checkboxAll: handleRowCheckboxChange,
- checkboxChange: handleRowCheckboxChange,
- },
-});
-</script>
-
-<template>
- <Page auto-content-height><FormModal @success="handleRefresh" />
- <BarcodeDetail ref="barcodeDetailRef" />
-
- <Grid table-title="鏉$爜鍒楄〃">
- <template #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: $t('ui.actionTitle.create', ['鏉$爜']),
- type: 'primary',
- icon: ACTION_ICON.ADD,
- auth: ['mes:wm-barcode:create'],
- onClick: handleCreate,
- },
- {
- label: $t('ui.actionTitle.deleteBatch'),
- type: 'primary',
- danger: true,
- icon: ACTION_ICON.DELETE,
- auth: ['mes:wm-barcode:delete'],
- disabled: checkedIds.length === 0,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [
- `${checkedIds.length} 鏉,
- ]),
- confirm: handleDeleteBatch,
- },
- },
- {
- label: '鏉$爜璁剧疆',
- type: 'primary',
- auth: ['mes:wm-barcode-config:query'],
- onClick: handleConfig,
- },
- {
- label: $t('ui.actionTitle.export'),
- type: 'primary',
- icon: ACTION_ICON.DOWNLOAD,
- auth: ['mes:wm-barcode:export'],
- onClick: handleExport,
- },
- ]"
- />
- </template>
- <template #barcode="{ row }">
- <div v-if="row.content" class="flex justify-center">
- <Barcode
- :content="row.content"
- :format="row.format"
- :height="60"
- :width="140"
- />
- </div>
- </template>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.detail'),
- type: 'link',
- auth: ['mes:wm-barcode:query'],
- onClick: handleView.bind(null, row),
- },
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- auth: ['mes:wm-barcode:update'],
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- auth: ['mes:wm-barcode:delete'],
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [
- row.bizName || row.bizCode || '',
- ]),
- confirm: handleDelete.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </Page>
-</template>
diff --git a/src/views/barcode/modules/form.vue b/src/views/barcode/modules/form.vue
deleted file mode 100644
index 41209ff..0000000
--- a/src/views/barcode/modules/form.vue
+++ /dev/null
@@ -1,111 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmBarcodeApi } from '#/api/mes/wm/barcode';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-import { BarcodeBizTypeEnum, CommonStatusEnum } from '@vben/constants';
-
-import { message } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import { createBarcode, getBarcode, updateBarcode } from '#/api/mes/wm/barcode';
-import { getWarehouseArea } from '#/api/mes/wm/warehouse/area';
-import { getWarehouseLocation } from '#/api/mes/wm/warehouse/location';
-import { $t } from '#/locales';
-
-import { useFormSchema } from '../data';
-
-const emit = defineEmits(['success']);
-
-const formData = ref<MesWmBarcodeApi.Barcode>();
-
-const getTitle = computed(() => {
- return formData.value?.id
- ? $t('ui.actionTitle.edit', ['鏉$爜'])
- : $t('ui.actionTitle.create', ['鏉$爜']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-2',
- labelWidth: 110,
- },
- layout: 'horizontal',
- schema: [],
- showDefaultActions: false,
-});
-
-/** 鍔犺浇绾ц仈閫夋嫨鍣ㄧ殑鏁版嵁锛堢紪杈戞椂鍥炲~涓婄骇浠撳簱/搴撳尯锛� */
-async function loadCascadeData(data: MesWmBarcodeApi.Barcode) {
- if (!data.bizType || !data.bizId) {
- return;
- }
- if (data.bizType === BarcodeBizTypeEnum.LOCATION) {
- const location = await getWarehouseLocation(data.bizId);
- if (location?.warehouseId) {
- await formApi.setFieldValue('locationWarehouseId', location.warehouseId);
- }
- } else if (data.bizType === BarcodeBizTypeEnum.AREA) {
- const area = await getWarehouseArea(data.bizId);
- await formApi.setValues({
- areaWarehouseId: area?.warehouseId,
- areaLocationId: area?.locationId,
- });
- }
-}
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data = (await formApi.getValues()) as MesWmBarcodeApi.Barcode;
- try {
- await (formData.value?.id
- ? updateBarcode({ ...data, id: formData.value.id })
- : createBarcode(data));
- // 鍏抽棴骞舵彁绀�
- await modalApi.close();
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- return;
- }
- formApi.setState({ schema: useFormSchema(formApi) });
- await formApi.setValues({ status: CommonStatusEnum.ENABLE });
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<MesWmBarcodeApi.Barcode>();
- if (!data || !data.id) {
- return;
- }
- modalApi.lock();
- try {
- formData.value = await getBarcode(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- await loadCascadeData(formData.value);
- } finally {
- modalApi.unlock();
- }
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-1/2">
- <Form class="mx-4" />
- </Modal>
-</template>
diff --git a/src/views/basicData/mdm/data.ts b/src/views/basicData/mdm/data.ts
index f294908..bbde65a 100644
--- a/src/views/basicData/mdm/data.ts
+++ b/src/views/basicData/mdm/data.ts
@@ -5,31 +5,29 @@
import { getDictOptions } from "#/packages/effects/hooks/src";
import { z } from '#/adapter/form';
+import { getItemTypeSimpleList } from '#/api/mes/md/item/type';
import { getUnitPage } from '#/api/mdm/unit';
-/** 鐗╂枡绫诲瀷閫夐」 */
-export const ITEM_TYPE_OPTIONS = [
- { label: "鍘熸枡", value: 1 },
- { label: "鍗婃垚鍝�", value: 2 },
- { label: "鎴愬搧", value: 3 },
- { label: "杈呮枡", value: 4 },
-];
+// 缂撳瓨鍗曚綅鍒楄〃
+let unitListCache: any[] | null = null;
+let unitListPromise: Promise<any[]> | null = null;
-/** 鐗╂枡绫诲瀷鏄犲皠 */
-export const ITEM_TYPE_MAP: Record<number, string> = {
- 1: "鍘熸枡",
- 2: "鍗婃垚鍝�",
- 3: "鎴愬搧",
- 4: "杈呮枡",
-};
-
-/** 鐗╂枡绫诲瀷棰滆壊鏄犲皠 */
-export const ITEM_TYPE_COLOR_MAP: Record<number, string> = {
- 1: "green",
- 2: "orange",
- 3: "blue",
- 4: "purple",
-};
+/** 鑾峰彇鍗曚綅鍒楄〃锛堝甫缂撳瓨锛� */
+async function getUnitListCached() {
+ if (unitListCache) {
+ return unitListCache;
+ }
+ if (unitListPromise) {
+ return unitListPromise;
+ }
+ unitListPromise = getUnitPage({ pageNo: 1, pageSize: 100, status: 0 }).then((res) => {
+ unitListCache = res.list || [];
+ return unitListCache;
+ }).finally(() => {
+ unitListPromise = null;
+ });
+ return unitListPromise;
+}
/** 鏂板/淇敼鐨勮〃鍗� */
export function useFormSchema(): VbenFormSchema[] {
@@ -61,15 +59,20 @@
rules: "required",
},
{
- component: "RadioGroup",
- fieldName: "itemType",
- label: "鐗╂枡绫诲瀷",
+ component: "ApiSelect",
+ fieldName: "categoryId",
+ label: "鐗╂枡鍒嗙被",
+ rules: "selectRequired",
componentProps: {
- options: ITEM_TYPE_OPTIONS,
- buttonStyle: "solid",
- optionType: "button",
+ placeholder: "璇烽�夋嫨鐗╂枡鍒嗙被",
+ allowClear: true,
+ api: async () => {
+ const res = await getItemTypeSimpleList();
+ return res || [];
+ },
+ labelField: "name",
+ valueField: "id",
},
- rules: "required",
},
{
component: "Input",
@@ -88,10 +91,7 @@
componentProps: {
placeholder: "璇烽�夋嫨璁¢噺鍗曚綅",
allowClear: true,
- api: async () => {
- const res = await getUnitPage({ pageNo: 1, pageSize: 100, status: 0 });
- return res.list || [];
- },
+ api: getUnitListCached,
labelField: "name",
valueField: "id",
},
@@ -104,10 +104,7 @@
componentProps: {
placeholder: "璇烽�夋嫨杈呭崟浣�1",
allowClear: true,
- api: async () => {
- const res = await getUnitPage({ pageNo: 1, pageSize: 100, status: 0 });
- return res.list || [];
- },
+ api: getUnitListCached,
labelField: "name",
valueField: "id",
},
@@ -132,10 +129,7 @@
componentProps: {
placeholder: "璇烽�夋嫨杈呭崟浣�2",
allowClear: true,
- api: async () => {
- const res = await getUnitPage({ pageNo: 1, pageSize: 100, status: 0 });
- return res.list || [];
- },
+ api: getUnitListCached,
labelField: "name",
valueField: "id",
},
@@ -238,13 +232,13 @@
component: 'Switch',
fieldName: 'isBatchManaged',
label: '鎵规绠$悊',
- defaultValue: true,
+ defaultValue: false,
componentProps: {
class: "w-auto",
checkedChildren: "鏄�",
unCheckedChildren: "鍚�",
},
- rules: z.boolean().default(true),
+ rules: z.boolean().default(false),
},
{
component: "Switch",
@@ -288,6 +282,126 @@
rows: 3,
},
},
+ // ===== 鎵规灞炴�ч厤缃紙isBatchManaged = true 鏃舵樉绀猴級 =====
+ {
+ component: "Divider",
+ fieldName: "batchConfigDivider",
+ label: "鎵规灞炴�ч厤缃�",
+ formItemClass: "col-span-2",
+ componentProps: {
+ orientation: "left",
+ plain: true,
+ },
+ dependencies: {
+ triggerFields: ["isBatchManaged"],
+ show: (values) => values.isBatchManaged === true,
+ },
+ },
+ {
+ component: "Switch",
+ fieldName: "produceDateFlag",
+ label: "鐢熶骇鏃ユ湡蹇呭~",
+ defaultValue: false,
+ componentProps: {
+ class: "w-auto",
+ checkedChildren: "鏄�",
+ unCheckedChildren: "鍚�",
+ },
+ dependencies: {
+ triggerFields: ["isBatchManaged"],
+ show: (values) => values.isBatchManaged === true,
+ },
+ },
+ {
+ component: "Switch",
+ fieldName: "expireDateFlag",
+ label: "鏈夋晥鏈熷繀濉�",
+ defaultValue: false,
+ componentProps: {
+ class: "w-auto",
+ checkedChildren: "鏄�",
+ unCheckedChildren: "鍚�",
+ },
+ dependencies: {
+ triggerFields: ["isBatchManaged"],
+ show: (values) => values.isBatchManaged === true,
+ },
+ },
+ {
+ component: "Switch",
+ fieldName: "receiptDateFlag",
+ label: "鍏ュ簱鏃ユ湡蹇呭~",
+ defaultValue: false,
+ componentProps: {
+ class: "w-auto",
+ checkedChildren: "鏄�",
+ unCheckedChildren: "鍚�",
+ },
+ dependencies: {
+ triggerFields: ["isBatchManaged"],
+ show: (values) => values.isBatchManaged === true,
+ },
+ },
+ {
+ component: "Switch",
+ fieldName: "vendorFlag",
+ label: "渚涘簲鍟嗗繀濉�",
+ defaultValue: false,
+ componentProps: {
+ class: "w-auto",
+ checkedChildren: "鏄�",
+ unCheckedChildren: "鍚�",
+ },
+ dependencies: {
+ triggerFields: ["isBatchManaged"],
+ show: (values) => values.isBatchManaged === true,
+ },
+ },
+ {
+ component: "Switch",
+ fieldName: "purchaseOrderCodeFlag",
+ label: "閲囪喘璁㈠崟鍙峰繀濉�",
+ defaultValue: false,
+ componentProps: {
+ class: "w-auto",
+ checkedChildren: "鏄�",
+ unCheckedChildren: "鍚�",
+ },
+ dependencies: {
+ triggerFields: ["isBatchManaged"],
+ show: (values) => values.isBatchManaged === true,
+ },
+ },
+ {
+ component: "Switch",
+ fieldName: "lotNumberFlag",
+ label: "鐢熶骇鎵瑰彿蹇呭~",
+ defaultValue: false,
+ componentProps: {
+ class: "w-auto",
+ checkedChildren: "鏄�",
+ unCheckedChildren: "鍚�",
+ },
+ dependencies: {
+ triggerFields: ["isBatchManaged"],
+ show: (values) => values.isBatchManaged === true,
+ },
+ },
+ {
+ component: "Switch",
+ fieldName: "qualityStatusFlag",
+ label: "璐ㄩ噺鐘舵�佸繀濉�",
+ defaultValue: false,
+ componentProps: {
+ class: "w-auto",
+ checkedChildren: "鏄�",
+ unCheckedChildren: "鍚�",
+ },
+ dependencies: {
+ triggerFields: ["isBatchManaged"],
+ show: (values) => values.isBatchManaged === true,
+ },
+ },
];
}
@@ -310,16 +424,6 @@
componentProps: {
placeholder: "璇疯緭鍏ョ墿鏂欏悕绉�",
allowClear: true,
- },
- },
- {
- fieldName: "itemType",
- label: "鐗╂枡绫诲瀷",
- component: "Select",
- componentProps: {
- placeholder: "璇烽�夋嫨鐗╂枡绫诲瀷",
- allowClear: true,
- options: ITEM_TYPE_OPTIONS,
},
},
{
@@ -355,6 +459,12 @@
minWidth: 150,
},
{
+ field: "categoryName",
+ title: "鐗╂枡鍒嗙被",
+ minWidth: 120,
+ slots: { default: "categoryName" },
+ },
+ {
field: "unitMeasureName",
title: "鍗曚綅",
minWidth: 80,
@@ -383,12 +493,6 @@
field: "warehouseName",
title: "榛樿浠撳簱",
minWidth: 100,
- },
- {
- field: "itemType",
- title: "鐗╂枡绫诲瀷",
- minWidth: 100,
- slots: { default: "itemType" },
},
{
field: "purchasePrice",
diff --git a/src/views/basicData/mdm/index.vue b/src/views/basicData/mdm/index.vue
index 16b34d4..7f87556 100644
--- a/src/views/basicData/mdm/index.vue
+++ b/src/views/basicData/mdm/index.vue
@@ -1,6 +1,7 @@
<script lang="ts" setup>
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { MdmItemApi } from '#/api/mdm/item';
+import type { MesMdItemTypeApi } from '#/api/mes/md/item/type';
import { ref } from 'vue';
@@ -17,9 +18,10 @@
getItemPage,
updateItemStatus,
} from '#/api/mdm/item';
+import { getItemTypeSimpleList } from '#/api/mes/md/item/type';
import { $t } from '#/locales';
-import { useGridColumns, useGridFormSchema, ITEM_TYPE_MAP, ITEM_TYPE_COLOR_MAP } from './data';
+import { useGridColumns, useGridFormSchema } from './data';
import Form from './modules/form.vue';
defineOptions({ name: 'MdmItem' });
@@ -28,6 +30,16 @@
connectedComponent: Form,
destroyOnClose: true,
});
+
+// 鍒嗙被鍒楄〃缂撳瓨
+const categoryList = ref<MesMdItemTypeApi.ItemType[]>([]);
+
+/** 鑾峰彇鍒嗙被鍚嶇О */
+function getCategoryName(categoryId?: number) {
+ if (!categoryId || !categoryList.value.length) return '';
+ const category = categoryList.value.find((item) => item.id === categoryId);
+ return category?.name || '';
+}
/** 鍒锋柊琛ㄦ牸 */
function handleRefresh() {
@@ -118,6 +130,14 @@
proxyConfig: {
ajax: {
query: async ({ page }, formValues) => {
+ // 鍔犺浇鍒嗙被鍒楄〃锛堢敤浜庢樉绀哄垎绫诲悕绉帮級
+ if (!categoryList.value.length) {
+ try {
+ categoryList.value = await getItemTypeSimpleList();
+ } catch {
+ categoryList.value = [];
+ }
+ }
return await getItemPage({
pageNo: page.currentPage,
pageSize: page.pageSize,
@@ -175,11 +195,13 @@
]"
/>
</template>
- <template #itemType="{ row }">
- <Tag v-if="row.itemType === 1" color="green">鍘熸枡</Tag>
- <Tag v-else-if="row.itemType === 2" color="orange">鍗婃垚鍝�</Tag>
- <Tag v-else-if="row.itemType === 3" color="blue">鎴愬搧</Tag>
- <Tag v-else-if="row.itemType === 4" color="purple">杈呮枡</Tag>
+ <template #categoryName="{ row }">
+ <Tag v-if="row.categoryId === 1" color="green">{{ getCategoryName(row.categoryId) }}</Tag>
+ <Tag v-else-if="row.categoryId === 2" color="orange">{{ getCategoryName(row.categoryId) }}</Tag>
+ <Tag v-else-if="row.categoryId === 3" color="blue">{{ getCategoryName(row.categoryId) }}</Tag>
+ <Tag v-else-if="row.categoryId === 4" color="purple">{{ getCategoryName(row.categoryId) }}</Tag>
+ <Tag v-else-if="row.categoryId === 5" color="cyan">{{ getCategoryName(row.categoryId) }}</Tag>
+ <span v-else>{{ getCategoryName(row.categoryId) }}</span>
</template>
<template #isBatchManaged="{ row }">
<Tag v-if="row.isBatchManaged" color="success">鏄�</Tag>
diff --git a/src/views/basicData/mdm/modules/form.vue b/src/views/basicData/mdm/modules/form.vue
index 83aa7a6..7cf30a7 100644
--- a/src/views/basicData/mdm/modules/form.vue
+++ b/src/views/basicData/mdm/modules/form.vue
@@ -1,37 +1,22 @@
<script lang="ts" setup>
import type { MdmItemApi } from '#/api/mdm/item';
-import type { MdmItemBatchConfigApi } from '#/api/mes/md/item-batch-config';
-import type { VbenFormApi } from '#/adapter/form';
-import { computed, ref, watch } from 'vue';
+import { ref } from 'vue';
- import { useVbenModal } from "#/packages/effects/common-ui/src";
+import { useVbenModal } from "#/packages/effects/common-ui/src";
- import { message } from "ant-design-vue";
+import { message } from "ant-design-vue";
import { useVbenForm } from '#/adapter/form';
import { createItem, getItem, updateItem } from '#/api/mdm/item';
-import { saveItemBatchConfig } from '#/api/mes/md/item-batch-config';
import { $t } from '#/locales';
import { useFormSchema } from '../data';
-import ItemBatchConfig from '../components/batch-config.vue';
- defineOptions({ name: "ItemForm" });
+defineOptions({ name: "ItemForm" });
const emit = defineEmits(['success']);
const formData = ref<MdmItemApi.Item>();
-const batchConfigRef = ref<InstanceType<typeof ItemBatchConfig>>();
-const batchConfig = ref<Partial<MdmItemBatchConfigApi.ItemBatchConfig>>({});
-
-// 褰撳墠琛ㄥ崟涓殑鎵规绠$悊寮�鍏冲�硷紙鐢ㄤ簬鎺у埗鎵规閰嶇疆鏄剧ず锛�
-const currentIsBatchManaged = ref<boolean>(false);
-
-const getTitle = computed(() => {
- return formData.value?.id
- ? $t('ui.actionTitle.edit', ['鐗╂枡'])
- : $t('ui.actionTitle.create', ['鐗╂枡']);
-});
const [Form, formApi] = useVbenForm({
commonConfig: {
@@ -44,10 +29,6 @@
schema: useFormSchema(),
showDefaultActions: false,
wrapperClass: 'grid-cols-2',
- // 鐩戝惉琛ㄥ崟鍊煎彉鍖�
- handleValuesChange: (values: any) => {
- currentIsBatchManaged.value = values?.isBatchManaged === true;
- },
});
const [Modal, modalApi] = useVbenModal({
@@ -59,18 +40,7 @@
modalApi.lock();
const data = (await formApi.getValues()) as MdmItemApi.Item;
try {
- // 淇濆瓨鐗╂枡鍩烘湰淇℃伅
- const itemId = await (formData.value?.id ? updateItem(data) : createItem(data));
- const savedItemId = typeof itemId === 'number' ? itemId : data.id;
-
- // 濡傛灉鍚敤鎵规绠$悊锛屼繚瀛樻壒娆¢厤缃�
- if (data.isBatchManaged && savedItemId) {
- await saveItemBatchConfig({
- ...batchConfig.value,
- itemId: savedItemId,
- });
- }
-
+ await (formData.value?.id ? updateItem(data) : createItem(data));
await modalApi.close();
emit('success');
message.success($t('ui.actionMessage.operationSuccess'));
@@ -81,8 +51,6 @@
async onOpenChange(isOpen: boolean) {
if (!isOpen) {
formData.value = undefined;
- batchConfig.value = {};
- currentIsBatchManaged.value = false;
return;
}
const data = modalApi.getData<MdmItemApi.Item>();
@@ -92,11 +60,6 @@
try {
formData.value = await getItem(data.id);
await formApi.setValues(formData.value);
- currentIsBatchManaged.value = formData.value?.isBatchManaged === true;
- // 鍔犺浇鎵规閰嶇疆
- if (batchConfigRef.value && currentIsBatchManaged.value) {
- await batchConfigRef.value.loadConfig();
- }
} finally {
modalApi.unlock();
}
@@ -104,27 +67,13 @@
// 鏂板妯″紡
formData.value = undefined;
await formApi.resetForm();
- // 鑾峰彇琛ㄥ崟榛樿鍊硷紙isBatchManaged 榛樿 true锛�
- const defaultValues = await formApi.getValues();
- currentIsBatchManaged.value = defaultValues?.isBatchManaged === true;
}
},
});
-
-/** 澶勭悊鎵规閰嶇疆鍙樺寲 */
-function handleBatchConfigChange(config: Partial<MdmItemBatchConfigApi.ItemBatchConfig>) {
- batchConfig.value = config;
-}
</script>
<template>
- <Modal class="w-[1000px]" :title="getTitle">
+ <Modal class="w-[1000px]" :title="formData?.id ? $t('ui.actionTitle.edit', ['鐗╂枡']) : $t('ui.actionTitle.create', ['鐗╂枡'])">
<Form class="mx-4" />
- <ItemBatchConfig
- ref="batchConfigRef"
- :item-id="formData?.id"
- :is-batch-managed="currentIsBatchManaged"
- @change="handleBatchConfigChange"
- />
</Modal>
</template>
diff --git a/src/views/batch/components/detail.vue b/src/views/batch/components/detail.vue
deleted file mode 100644
index 2f0dff0..0000000
--- a/src/views/batch/components/detail.vue
+++ /dev/null
@@ -1,52 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmBatchApi } from '#/api/mes/wm/batch';
-
-import { ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { getBatch } from '#/api/mes/wm/batch';
-import { useDescription } from '#/components/description';
-
-import { useDetailSchema } from '../data';
-
-const detailData = ref<MesWmBatchApi.Batch>(); // 褰撳墠鎵规璇︽儏
-
-const [Descriptions] = useDescription({
- bordered: true,
- column: 3,
- schema: useDetailSchema(),
- useCard: false,
-});
-
-const [Modal, modalApi] = useVbenModal({
- showCancelButton: false,
- showConfirmButton: false,
- async onOpenChange(isOpen) {
- if (!isOpen) {
- detailData.value = undefined;
- return;
- }
- const data = modalApi.getData<{ id?: number }>();
- if (!data?.id) {
- return;
- }
- modalApi.lock();
- try {
- detailData.value = await getBatch(data.id);
- } finally {
- modalApi.unlock();
- }
- },
-});
-
-defineExpose({
- open: (id: number) => modalApi.setData({ id }).open(),
-});
-</script>
-
-<template>
- <Modal title="鎵规璇︽儏" class="w-3/5">
- <Descriptions class="mx-4" :data="detailData" />
- </Modal>
-</template>
diff --git a/src/views/batch/components/index.ts b/src/views/batch/components/index.ts
deleted file mode 100644
index e4b0401..0000000
--- a/src/views/batch/components/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export { default as WmBatchDetail } from './detail.vue';
-export { default as WmBatchSelectDialog } from './select-dialog.vue';
-export { default as WmBatchSelect } from './select.vue';
diff --git a/src/views/batch/components/select-dialog.vue b/src/views/batch/components/select-dialog.vue
deleted file mode 100644
index 82c5f67..0000000
--- a/src/views/batch/components/select-dialog.vue
+++ /dev/null
@@ -1,255 +0,0 @@
-<script lang="ts" setup>
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmBatchApi } from '#/api/mes/wm/batch';
-
-import { computed, nextTick, ref } from 'vue';
-
-import { Alert, Button, message, Modal } from 'ant-design-vue';
-
-import { useVbenVxeGrid } from '#/adapter/vxe-table';
-import { getBatchPage } from '#/api/mes/wm/batch';
-
-import {
- useBatchSelectGridColumns,
- useBatchSelectGridFormSchema,
-} from '../data';
-
-const emit = defineEmits<{
- selected: [rows: MesWmBatchApi.Batch[]];
-}>();
-
-const open = ref(false); // 寮圭獥鏄惁鎵撳紑
-const multiple = ref(false); // 鏄惁澶氶�夛紱榛樿鎸夊崟閫夐�夋嫨鍣ㄤ娇鐢�
-const selectedRows = ref<MesWmBatchApi.Batch[]>([]); // 宸查�夋壒娆″垪琛�
-const preSelectedIds = ref<number[]>([]); // 棰勯�夋壒娆$紪鍙峰垪琛�
-const externalItemId = ref<number>(); // 澶栭儴浼犲叆鐨勯粯璁ょ墿鏂欒繃婊�
-const externalClientId = ref<number>(); // 澶栭儴浼犲叆鐨勯粯璁ゅ鎴疯繃婊�
-const externalVendorId = ref<number>(); // 澶栭儴浼犲叆鐨勯粯璁や緵搴斿晢杩囨护
-const externalSalesOrderCode = ref<string>(); // 澶栭儴浼犲叆鐨勯粯璁ら攢鍞鍗曡繃婊�
-
-const filterTip = computed(() => {
- const parts: string[] = [];
- if (externalClientId.value !== null) {
- parts.push('瀹㈡埛');
- }
- if (externalVendorId.value !== null) {
- parts.push('渚涘簲鍟�');
- }
- if (externalSalesOrderCode.value !== null) {
- parts.push('閿�鍞鍗�');
- }
- return parts.length > 0 ? `宸叉寜${parts.join('/')}棰勮繃婊 : '';
-});
-
-/** 鑾峰彇澶氶�夎褰曪紝鍖呭惈 VXE reserve 璺ㄩ〉璁板綍 */
-function getMultipleSelectedRows() {
- const selectedMap = new Map<number, MesWmBatchApi.Batch>();
- const records = [
- ...(gridApi.grid.getCheckboxReserveRecords?.() ?? []),
- ...(gridApi.grid.getCheckboxRecords?.() ?? []),
- ] as MesWmBatchApi.Batch[];
- records.forEach((row) => {
- const rowId = row.id;
- if (rowId !== undefined) {
- selectedMap.set(rowId, row);
- }
- });
- return [...selectedMap.values()];
-}
-
-/** 澶勭悊澶氶�夊嬀閫夊彉鍖� */
-function handleCheckboxSelectChange() {
- selectedRows.value = getMultipleSelectedRows();
-}
-
-/** 澶勭悊鍗曢�夊垏鎹� */
-function handleRadioChange(row: MesWmBatchApi.Batch) {
- selectedRows.value = [row];
-}
-
-/** 澶氶�夋ā寮忎笅鍒囨崲琛屽嬀閫� */
-async function toggleMultipleRow(row: MesWmBatchApi.Batch) {
- const selected = gridApi.grid.isCheckedByCheckboxRow(row);
- await gridApi.grid.setCheckboxRow(row, !selected);
- selectedRows.value = getMultipleSelectedRows();
-}
-
-/** 澶勭悊琛屽弻鍑伙細鍗曢�夌洿鎺ョ‘璁わ紝澶氶�夊垏鎹㈠嬀閫� */
-async function handleCellDblclick({ row }: { row: MesWmBatchApi.Batch }) {
- if (multiple.value) {
- await toggleMultipleRow(row);
- return;
- }
- selectedRows.value = [row];
- await gridApi.grid.setRadioRow(row);
- handleConfirm();
-}
-
-/** 鍥炴樉棰勯�夋壒娆� */
-async function applyPreSelection() {
- if (preSelectedIds.value.length === 0) {
- return;
- }
- const rows = gridApi.grid.getData() as MesWmBatchApi.Batch[];
- for (const row of rows) {
- if (
- row.id === undefined ||
- row.id === null ||
- !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();
- }
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- formOptions: {
- schema: useBatchSelectGridFormSchema(),
- },
- gridOptions: {
- columns: useBatchSelectGridColumns(false),
- height: 520,
- keepSource: true,
- checkboxConfig: {
- highlight: true,
- range: true,
- reserve: true,
- },
- radioConfig: {
- highlight: true,
- trigger: 'row',
- },
- proxyConfig: {
- ajax: {
- query: async ({ page }, formValues) => {
- return await getBatchPage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- ...formValues,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- search: true,
- },
- } as VxeTableGridOptions<MesWmBatchApi.Batch>,
- gridEvents: {
- cellDblclick: handleCellDblclick,
- checkboxAll: handleCheckboxSelectChange,
- checkboxChange: handleCheckboxSelectChange,
- radioChange: ({ row }: { row: MesWmBatchApi.Batch }) => {
- handleRadioChange(row);
- },
- },
-});
-
-/** 閲嶇疆鏌ヨ鍜岄�夋嫨鐘舵�侊紝淇濈暀澶栭儴浼犲叆鐨勯粯璁よ繃婊� */
-async function resetQueryState() {
- selectedRows.value = [];
- await gridApi.grid.clearCheckboxRow();
- await gridApi.grid.clearCheckboxReserve();
- await gridApi.grid.clearRadioRow();
- await gridApi.formApi.resetForm();
- if (externalItemId.value) {
- await gridApi.formApi.setFieldValue('itemId', externalItemId.value);
- }
- if (externalClientId.value) {
- await gridApi.formApi.setFieldValue('clientId', externalClientId.value);
- }
- if (externalVendorId.value) {
- await gridApi.formApi.setFieldValue('vendorId', externalVendorId.value);
- }
- if (externalSalesOrderCode.value) {
- await gridApi.formApi.setFieldValue(
- 'salesOrderCode',
- externalSalesOrderCode.value,
- );
- }
-}
-
-/** 鎵撳紑鎵规閫夋嫨寮圭獥 */
-async function openModal(
- selectedIds?: number[],
- options?: {
- clientId?: number;
- itemId?: number;
- multiple?: boolean;
- salesOrderCode?: string;
- vendorId?: number;
- },
-) {
- open.value = true;
- multiple.value = options?.multiple ?? false;
- preSelectedIds.value = selectedIds || [];
- externalItemId.value = options?.itemId;
- externalClientId.value = options?.clientId;
- externalVendorId.value = options?.vendorId;
- externalSalesOrderCode.value = options?.salesOrderCode;
- await nextTick();
- gridApi.setGridOptions({
- columns: useBatchSelectGridColumns(multiple.value),
- });
- await resetQueryState();
- await gridApi.query();
- await nextTick();
- await applyPreSelection();
-}
-
-/** 鍏抽棴鎵规閫夋嫨寮圭獥 */
-function closeModal() {
- open.value = false;
-}
-
-/** 纭閫夋嫨鎵规 */
-function handleConfirm() {
- const rows = multiple.value ? getMultipleSelectedRows() : selectedRows.value;
- if (rows.length === 0) {
- message.warning(multiple.value ? '璇疯嚦灏戦�夋嫨涓�鏉℃暟鎹�' : '璇烽�夋嫨涓�鏉℃暟鎹�');
- return;
- }
- emit('selected', multiple.value ? rows : [rows[0]!]);
- open.value = false;
-}
-
-defineExpose({ open: openModal });
-</script>
-
-<template>
- <Modal
- v-model:open="open"
- title="鎵规閫夋嫨"
- width="80%"
- :destroy-on-close="true"
- @ok="handleConfirm"
- @cancel="closeModal"
- >
- <Alert
- v-if="filterTip"
- :message="filterTip"
- type="info"
- show-icon
- class="!mb-3"
- />
- <Grid table-title="鎵规鍒楄〃" />
- <template #footer>
- <Button @click="closeModal">鍙栨秷</Button>
- <Button type="primary" @click="handleConfirm">纭畾</Button>
- </template>
- </Modal>
-</template>
diff --git a/src/views/batch/components/select.vue b/src/views/batch/components/select.vue
deleted file mode 100644
index 4564f60..0000000
--- a/src/views/batch/components/select.vue
+++ /dev/null
@@ -1,149 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmBatchApi } from '#/api/mes/wm/batch';
-
-import { computed, ref, useAttrs, watch } from 'vue';
-
-import { IconifyIcon } from '@vben/icons';
-
-import { Input, Tooltip } from 'ant-design-vue';
-
-import { getBatch } from '#/api/mes/wm/batch';
-
-import WmBatchSelectDialog from './select-dialog.vue';
-
-defineOptions({ name: 'WmBatchSelect', inheritAttrs: false });
-
-const props = withDefaults(
- defineProps<{
- allowClear?: boolean;
- clientId?: number; // 榛樿杩囨护鐨勫鎴� ID
- disabled?: boolean;
- itemId?: number; // 榛樿杩囨护鐨勭墿鏂� ID
- modelValue?: number;
- placeholder?: string;
- salesOrderCode?: string; // 榛樿杩囨护鐨勯攢鍞鍗曠紪鍙�
- vendorId?: number; // 榛樿杩囨护鐨勪緵搴斿晢 ID
- }>(),
- {
- allowClear: true,
- clientId: undefined,
- disabled: false,
- itemId: undefined,
- modelValue: undefined,
- placeholder: '璇烽�夋嫨鎵规',
- salesOrderCode: undefined,
- vendorId: undefined,
- },
-);
-
-const emit = defineEmits<{
- change: [item: MesWmBatchApi.Batch | undefined];
- 'update:modelValue': [value: number | undefined];
-}>();
-
-const attrs = useAttrs();
-const dialogRef = ref<InstanceType<typeof WmBatchSelectDialog>>();
-const hovering = ref(false);
-const selectedItem = ref<MesWmBatchApi.Batch>();
-
-const displayLabel = computed(() => selectedItem.value?.code ?? '');
-
-const showClear = computed(
- () =>
- props.allowClear &&
- !props.disabled &&
- hovering.value &&
- props.modelValue !== null,
-);
-
-/** 鏍规嵁缂栧彿鍗曟潯鏌ヨ鎵规淇℃伅锛堢敤浜庣紪杈戝洖鏄撅級 */
-async function resolveItemById(id: number | undefined) {
- if (!id) {
- selectedItem.value = undefined;
- return;
- }
- if (selectedItem.value?.id === id) {
- return;
- }
- selectedItem.value = await getBatch(id);
-}
-
-watch(() => props.modelValue, resolveItemById, { 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]
- ) as number[];
- dialogRef.value?.open(selectedIds, {
- clientId: props.clientId,
- itemId: props.itemId,
- multiple: false,
- salesOrderCode: props.salesOrderCode,
- vendorId: props.vendorId,
- });
-}
-
-/** 寮圭獥閫変腑鍥炶皟 */
-function handleSelected(rows: MesWmBatchApi.Batch[]) {
- const item = rows[0];
- if (!item) {
- return;
- }
- selectedItem.value = item;
- emit('update:modelValue', item.id);
- emit('change', item);
-}
-</script>
-
-<template>
- <div
- v-bind="attrs"
- class="w-full"
- :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.itemCode || '-' }}</div>
- <div>鐗╂枡鍚嶇О锛歿{ selectedItem.itemName || '-' }}</div>
- <div>鐢熶骇鎵瑰彿锛歿{ selectedItem.lotNumber || '-' }}</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>
- <WmBatchSelectDialog ref="dialogRef" @selected="handleSelected" />
-</template>
diff --git a/src/views/batch/data.ts b/src/views/batch/data.ts
deleted file mode 100644
index 9af407b..0000000
--- a/src/views/batch/data.ts
+++ /dev/null
@@ -1,372 +0,0 @@
-锘縤mport type { VbenFormSchema } from '#/adapter/form';
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmBatchApi } from '#/api/mes/wm/batch';
-import type { DescriptionItemSchema } from '#/components/description';
-
-import { h, markRaw } from 'vue';
-
-import { DICT_TYPE } from '@vben/constants';
-import { getDictOptions } from '@vben/hooks';
-import { formatDate } from '@vben/utils';
-
-import { DictTag } from '#/components/dict-tag';
-import { getRangePickerDefaultProps } from '#/utils';
-import { MdClientSelect } from '#/views/mes/md/client/components';
-import { MdItemSelect } from '#/views/mes/md/item/components';
-import { MdVendorSelect } from '#/views/mes/md/vendor/components';
-import { MdWorkstationSelect } from '#/views/mes/md/workstation/components';
-import { ProTaskSelect } from '#/views/mes/pro/task/components';
-import { ProWorkOrderSelect } from '#/views/mes/pro/workorder/components';
-import { TmToolSelect } from '#/views/mes/tm/tool/components';
-
-/** 鎵规閫夋嫨寮圭獥鐨勬悳绱㈣〃鍗� */
-export function useBatchSelectGridFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'code',
- label: '鎵规缂栧彿',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ユ壒娆$紪鍙�',
- },
- },
- {
- fieldName: 'itemId',
- label: '浜у搧鐗╂枡',
- component: markRaw(MdItemSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨浜у搧鐗╂枡',
- },
- },
- {
- fieldName: 'vendorId',
- label: '渚涘簲鍟�',
- component: markRaw(MdVendorSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨渚涘簲鍟�',
- },
- },
- {
- fieldName: 'clientId',
- label: '瀹㈡埛',
- component: markRaw(MdClientSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨瀹㈡埛',
- },
- },
- {
- fieldName: 'workOrderId',
- label: '鐢熶骇璁㈠崟',
- component: markRaw(ProWorkOrderSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨鐢熶骇璁㈠崟',
- },
- },
- {
- fieldName: 'workstationId',
- label: '宸ヤ綔绔�',
- component: markRaw(MdWorkstationSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨宸ヤ綔绔�',
- },
- },
- {
- fieldName: 'taskId',
- label: '鐢熶骇浠诲姟',
- component: markRaw(ProTaskSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨鐢熶骇浠诲姟',
- },
- },
- {
- fieldName: 'toolId',
- label: '宸ュ叿',
- component: markRaw(TmToolSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨宸ュ叿',
- },
- },
- {
- fieldName: 'moldId',
- label: '妯″叿缂栧彿',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ユā鍏风紪鍙�',
- },
- },
- {
- fieldName: 'salesOrderCode',
- label: '閿�鍞鍗曠紪鍙�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ラ攢鍞鍗曠紪鍙�',
- },
- },
- {
- fieldName: 'purchaseOrderCode',
- label: '閲囪喘璁㈠崟缂栧彿',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ラ噰璐鍗曠紪鍙�',
- },
- },
- {
- fieldName: 'lotNumber',
- label: '鐢熶骇鎵瑰彿',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ョ敓浜ф壒鍙�',
- },
- },
- {
- fieldName: 'qualityStatus',
- label: '璐ㄩ噺鐘舵��',
- component: 'Select',
- componentProps: {
- allowClear: true,
- options: getDictOptions(DICT_TYPE.MES_WM_QUALITY_STATUS, 'number'),
- placeholder: '璇烽�夋嫨璐ㄩ噺鐘舵��',
- },
- },
- {
- fieldName: 'produceDate',
- label: '鐢熶骇鏃ユ湡',
- component: 'RangePicker',
- componentProps: {
- ...getRangePickerDefaultProps(),
- allowClear: true,
- },
- },
- {
- fieldName: 'expireDate',
- label: '鏈夋晥鏈�',
- component: 'RangePicker',
- componentProps: {
- ...getRangePickerDefaultProps(),
- allowClear: true,
- },
- },
- {
- fieldName: 'receiptDate',
- label: '鍏ュ簱鏃ユ湡',
- component: 'RangePicker',
- componentProps: {
- ...getRangePickerDefaultProps(),
- allowClear: true,
- },
- },
- ];
-}
-
-/** 鎵规閫夋嫨寮圭獥鐨勫瓧娈� */
-export function useBatchSelectGridColumns(
- multiple = false,
-): VxeTableGridOptions<MesWmBatchApi.Batch>['columns'] {
- return [
- {
- type: multiple ? 'checkbox' : 'radio',
- width: 50,
- },
- {
- field: 'code',
- title: '鎵规缂栧彿',
- width: 150,
- },
- {
- field: 'itemCode',
- title: '鐗╂枡缂栫爜',
- width: 150,
- },
- {
- field: 'itemName',
- title: '鐗╂枡鍚嶇О',
- minWidth: 140,
- },
- {
- field: 'itemSpecification',
- title: '瑙勬牸鍨嬪彿',
- width: 120,
- },
- {
- field: 'unitName',
- title: '鍗曚綅',
- width: 80,
- },
- {
- field: 'vendorCode',
- title: '渚涘簲鍟嗙紪鐮�',
- width: 120,
- },
- {
- field: 'vendorName',
- title: '渚涘簲鍟嗗悕绉�',
- width: 120,
- },
- {
- field: 'clientCode',
- title: '瀹㈡埛缂栫爜',
- width: 110,
- },
- {
- field: 'clientName',
- title: '瀹㈡埛鍚嶇О',
- width: 110,
- },
- {
- field: 'salesOrderCode',
- title: '閿�鍞鍗曠紪鍙�',
- width: 140,
- },
- {
- field: 'purchaseOrderCode',
- title: '閲囪喘璁㈠崟缂栧彿',
- width: 140,
- },
- {
- field: 'workOrderCode',
- title: '璁㈠崟缂栫爜',
- width: 140,
- },
- {
- field: 'workstationCode',
- title: '宸ヤ綔绔欑紪鐮�',
- width: 120,
- },
- {
- field: 'taskCode',
- title: '鐢熶骇浠诲姟缂栧彿',
- width: 140,
- },
- {
- field: 'toolCode',
- title: '宸ュ叿缂栧彿',
- width: 120,
- },
- {
- field: 'lotNumber',
- title: '鐢熶骇鎵瑰彿',
- width: 120,
- },
- {
- field: 'qualityStatus',
- title: '璐ㄩ噺鐘舵��',
- width: 100,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_QUALITY_STATUS },
- },
- },
- {
- field: 'produceDate',
- title: '鐢熶骇鏃ユ湡',
- width: 120,
- formatter: 'formatDate',
- },
- {
- field: 'expireDate',
- title: '鏈夋晥鏈�',
- width: 120,
- formatter: 'formatDate',
- },
- {
- field: 'receiptDate',
- title: '鍏ュ簱鏃ユ湡',
- width: 120,
- formatter: 'formatDate',
- },
- ];
-}
-
-/** 鎵规璇︽儏鐨勬弿杩板瓧娈� */
-export function useDetailSchema(): DescriptionItemSchema[] {
- return [
- {
- field: 'code',
- label: '鎵规缂栧彿',
- },
- {
- field: 'itemCode',
- label: '鐗╂枡缂栫爜',
- },
- {
- field: 'itemName',
- label: '鐗╂枡鍚嶇О',
- },
- {
- field: 'itemSpecification',
- label: '瑙勬牸鍨嬪彿',
- },
- {
- field: 'unitName',
- label: '鍗曚綅',
- },
- {
- field: 'lotNumber',
- label: '鐢熶骇鎵瑰彿',
- },
- {
- field: 'produceDate',
- label: '鐢熶骇鏃ユ湡',
- render: (value) => (value ? formatDate(value, 'YYYY-MM-DD') : '-'),
- },
- {
- field: 'expireDate',
- label: '鏈夋晥鏈�',
- render: (value) => (value ? formatDate(value, 'YYYY-MM-DD') : '-'),
- },
- {
- field: 'receiptDate',
- label: '鍏ュ簱鏃ユ湡',
- render: (value) => (value ? formatDate(value, 'YYYY-MM-DD') : '-'),
- },
- {
- field: 'vendorName',
- label: '渚涘簲鍟�',
- render: (value) => value || '-',
- },
- {
- field: 'clientName',
- label: '瀹㈡埛',
- render: (value) => value || '-',
- },
- {
- field: 'workstationCode',
- label: '宸ヤ綔绔�',
- render: (value) => value || '-',
- },
- {
- field: 'purchaseOrderCode',
- label: '閲囪喘璁㈠崟缂栧彿',
- render: (value) => value || '-',
- },
- {
- field: 'salesOrderCode',
- label: '閿�鍞鍗曠紪鍙�',
- render: (value) => value || '-',
- },
- {
- field: 'workOrderCode',
- label: '鐢熶骇璁㈠崟',
- render: (value) => value || '-',
- },
- {
- field: 'qualityStatus',
- label: '璐ㄩ噺鐘舵��',
- render: (value) =>
- value === null
- ? '-'
- : h(DictTag, { type: DICT_TYPE.MES_WM_QUALITY_STATUS, value }),
- },
- {
- field: 'remark',
- label: '澶囨敞',
- span: 3,
- render: (value) => value || '-',
- },
- ];
-}
diff --git a/src/views/erp/purchase/supplier/components/index.ts b/src/views/erp/purchase/supplier/components/index.ts
new file mode 100644
index 0000000..cdd1813
--- /dev/null
+++ b/src/views/erp/purchase/supplier/components/index.ts
@@ -0,0 +1,2 @@
+export { default as ErpSupplierSelectDialog } from './select-dialog.vue';
+export { default as ErpSupplierSelect } from './select.vue';
diff --git a/src/views/stocktaking/plan/components/select-dialog.vue b/src/views/erp/purchase/supplier/components/select-dialog.vue
similarity index 64%
rename from src/views/stocktaking/plan/components/select-dialog.vue
rename to src/views/erp/purchase/supplier/components/select-dialog.vue
index 9883491..0822d10 100644
--- a/src/views/stocktaking/plan/components/select-dialog.vue
+++ b/src/views/erp/purchase/supplier/components/select-dialog.vue
@@ -1,6 +1,6 @@
<script lang="ts" setup>
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmStockTakingPlanApi } from '#/api/mes/wm/stocktaking/plan';
+import type { ErpSupplierApi } from '#/api/erp/purchase/supplier';
import { nextTick, ref } from 'vue';
@@ -9,60 +9,53 @@
import { message, Modal } from 'ant-design-vue';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
-import { getStockTakingPlanPage } from '#/api/mes/wm/stocktaking/plan';
+import { getSupplierPage } from '#/api/erp/purchase/supplier';
-import { useSelectGridColumns, useSelectGridFormSchema } from '../data';
+defineOptions({ name: 'ErpSupplierSelectDialog' });
const emit = defineEmits<{
- selected: [rows: MesWmStockTakingPlanApi.StockTakingPlan[]];
+ selected: [rows: ErpSupplierApi.Supplier[]];
}>();
-const open = ref(false); // 寮圭獥鏄惁鎵撳紑
-const multiple = ref(true); // 鏄惁澶氶��
-const selectedRows = ref<MesWmStockTakingPlanApi.StockTakingPlan[]>([]); // 宸查�夌洏鐐规柟妗�
-const preSelectedIds = ref<number[]>([]); // 棰勯�夌洏鐐规柟妗堢紪鍙�
+const open = ref(false);
+const multiple = ref(true);
+const selectedRows = ref<ErpSupplierApi.Supplier[]>([]);
+const preSelectedIds = ref<number[]>([]);
-/** 鑾峰彇澶氶�夎褰曪紝鍖呭惈 VXE reserve 璺ㄩ〉璁板綍 */
+function getTableRows() {
+ return gridApi.grid.getTableData().fullData as ErpSupplierApi.Supplier[];
+}
+
function getMultipleSelectedRows() {
- const selectedMap = new Map<
- number,
- MesWmStockTakingPlanApi.StockTakingPlan
- >();
+ const selectedMap = new Map<number, ErpSupplierApi.Supplier>();
const records = [
...(gridApi.grid.getCheckboxReserveRecords?.() ?? []),
...(gridApi.grid.getCheckboxRecords?.() ?? []),
- ] as MesWmStockTakingPlanApi.StockTakingPlan[];
+ ] as ErpSupplierApi.Supplier[];
records.forEach((row) => {
- if (row.id !== undefined && row.id !== null) {
- selectedMap.set(row.id, row);
+ const rowId = row.id;
+ if (rowId) {
+ selectedMap.set(rowId, row);
}
});
return [...selectedMap.values()];
}
-/** 澶勭悊鍕鹃�夊彉鍖� */
function handleCheckboxSelectChange() {
selectedRows.value = getMultipleSelectedRows();
}
-/** 澶勭悊鍗曢�夊彉鍖� */
-function handleRadioChange(row: MesWmStockTakingPlanApi.StockTakingPlan) {
+function handleRadioChange(row: ErpSupplierApi.Supplier) {
selectedRows.value = [row];
}
-/** 澶氶�夋ā寮忎笅鍒囨崲琛屽嬀閫� */
-async function toggleMultipleRow(row: MesWmStockTakingPlanApi.StockTakingPlan) {
+async function toggleMultipleRow(row: ErpSupplierApi.Supplier) {
const selected = gridApi.grid.isCheckedByCheckboxRow(row);
await gridApi.grid.setCheckboxRow(row, !selected);
selectedRows.value = getMultipleSelectedRows();
}
-/** 澶勭悊琛屽弻鍑伙細鍗曢�夌洿鎺ョ‘璁わ紱澶氶�夊垏鎹㈠嬀閫� */
-async function handleCellDblclick({
- row,
-}: {
- row: MesWmStockTakingPlanApi.StockTakingPlan;
-}) {
+async function handleCellDblclick({ row }: { row: ErpSupplierApi.Supplier }) {
if (multiple.value) {
await toggleMultipleRow(row);
return;
@@ -72,13 +65,11 @@
handleConfirm();
}
-/** 鍥炴樉棰勯�夌洏鐐规柟妗� */
async function applyPreSelection() {
if (preSelectedIds.value.length === 0) {
return;
}
- const rows =
- gridApi.grid.getData() as MesWmStockTakingPlanApi.StockTakingPlan[];
+ const rows = getTableRows();
for (const row of rows) {
if (
row.id === undefined ||
@@ -100,13 +91,56 @@
}
}
+function useSelectGridFormSchema() {
+ return [
+ {
+ fieldName: 'name',
+ label: '渚涘簲鍟嗗悕绉�',
+ component: 'Input',
+ componentProps: {
+ placeholder: '璇疯緭鍏ヤ緵搴斿晢鍚嶇О',
+ allowClear: true,
+ },
+ },
+ ];
+}
+
+function useSelectGridColumns(multiple = false): VxeTableGridOptions<ErpSupplierApi.Supplier>['columns'] {
+ return [
+ {
+ type: multiple ? 'checkbox' : 'radio',
+ width: 50,
+ },
+ {
+ field: 'name',
+ title: '渚涘簲鍟嗗悕绉�',
+ minWidth: 150,
+ },
+ {
+ field: 'contact',
+ title: '鑱旂郴浜�',
+ minWidth: 120,
+ },
+ {
+ field: 'mobile',
+ title: '鎵嬫満鍙风爜',
+ minWidth: 130,
+ },
+ {
+ field: 'telephone',
+ title: '鑱旂郴鐢佃瘽',
+ minWidth: 130,
+ },
+ ];
+}
+
const [Grid, gridApi] = useVbenVxeGrid({
formOptions: {
schema: useSelectGridFormSchema(),
},
gridOptions: {
columns: useSelectGridColumns(true),
- height: 480,
+ height: 520,
keepSource: true,
checkboxConfig: {
highlight: true,
@@ -120,11 +154,10 @@
proxyConfig: {
ajax: {
query: async ({ page }, formValues) => {
- return await getStockTakingPlanPage({
+ return await getSupplierPage({
pageNo: page.currentPage,
pageSize: page.pageSize,
...formValues,
- // 閫夋嫨鍣ㄥ彧灞曠ず鍚敤鐘舵�佺殑鏂规
status: CommonStatusEnum.ENABLE,
});
},
@@ -138,22 +171,17 @@
refresh: true,
search: true,
},
- } as VxeTableGridOptions<MesWmStockTakingPlanApi.StockTakingPlan>,
+ } as VxeTableGridOptions<ErpSupplierApi.Supplier>,
gridEvents: {
cellDblclick: handleCellDblclick,
checkboxAll: handleCheckboxSelectChange,
checkboxChange: handleCheckboxSelectChange,
- radioChange: ({
- row,
- }: {
- row: MesWmStockTakingPlanApi.StockTakingPlan;
- }) => {
+ radioChange: ({ row }: { row: ErpSupplierApi.Supplier }) => {
handleRadioChange(row);
},
},
});
-/** 閲嶇疆鏌ヨ鍜岄�夋嫨鐘舵�� */
async function resetQueryState() {
selectedRows.value = [];
await gridApi.grid.clearCheckboxRow();
@@ -162,7 +190,6 @@
await gridApi.formApi.resetForm();
}
-/** 鎵撳紑鐩樼偣鏂规閫夋嫨寮圭獥 */
async function openModal(
selectedIds?: number[],
options?: { multiple?: boolean },
@@ -180,12 +207,11 @@
await applyPreSelection();
}
-/** 鍏抽棴寮圭獥 */
-function closeModal() {
+async function closeModal() {
open.value = false;
+ await resetQueryState();
}
-/** 纭閫夋嫨 */
function handleConfirm() {
const rows = multiple.value ? getMultipleSelectedRows() : selectedRows.value;
if (rows.length === 0) {
@@ -202,12 +228,12 @@
<template>
<Modal
v-model:open="open"
- :destroy-on-close="true"
- title="鐩樼偣鏂规閫夋嫨"
+ title="渚涘簲鍟嗛�夋嫨"
width="70%"
- @cancel="closeModal"
+ :destroy-on-close="true"
@ok="handleConfirm"
+ @cancel="closeModal"
>
- <Grid table-title="鐩樼偣鏂规鍒楄〃" />
+ <Grid table-title="渚涘簲鍟嗗垪琛�" />
</Modal>
</template>
diff --git a/src/views/erp/purchase/supplier/components/select.vue b/src/views/erp/purchase/supplier/components/select.vue
new file mode 100644
index 0000000..10cffa5
--- /dev/null
+++ b/src/views/erp/purchase/supplier/components/select.vue
@@ -0,0 +1,114 @@
+<script lang="ts" setup>
+import type { ErpSupplierApi } from '#/api/erp/purchase/supplier';
+
+import { computed, ref, useAttrs } from 'vue';
+
+import { IconifyIcon } from '@vben/icons';
+
+import { Input, Tooltip } from 'ant-design-vue';
+
+import ErpSupplierSelectDialog from './select-dialog.vue';
+
+defineOptions({ name: 'ErpSupplierSelect', inheritAttrs: false });
+
+const props = withDefaults(
+ defineProps<{
+ allowClear?: boolean;
+ disabled?: boolean;
+ modelValue?: number;
+ placeholder?: string;
+ supplierName?: string;
+ }>(),
+ {
+ allowClear: true,
+ disabled: false,
+ modelValue: undefined,
+ placeholder: '璇烽�夋嫨渚涘簲鍟�',
+ supplierName: undefined,
+ },
+);
+const emit = defineEmits<{
+ change: [item: ErpSupplierApi.Supplier | undefined];
+ 'update:modelValue': [value: number | undefined];
+}>();
+const attrs = useAttrs();
+const dialogRef = ref<InstanceType<typeof ErpSupplierSelectDialog>>();
+const hovering = ref(false);
+const selectedItem = ref<ErpSupplierApi.Supplier>();
+
+const displayLabel = computed(() => props.supplierName || selectedItem.value?.name || '');
+const showClear = computed(
+ () =>
+ props.allowClear &&
+ !props.disabled &&
+ hovering.value &&
+ props.modelValue !== null,
+);
+
+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]
+ ) as number[];
+ dialogRef.value?.open(selectedIds, { multiple: false });
+}
+
+function handleSelected(rows: ErpSupplierApi.Supplier[]) {
+ const item = rows[0];
+ if (!item) {
+ return;
+ }
+ selectedItem.value = item;
+ emit('update:modelValue', item.id);
+ emit('change', item);
+}
+</script>
+
+<template>
+ <div
+ v-bind="attrs"
+ class="w-full"
+ :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.name || '-' }}</div>
+ <div>鑱旂郴浜猴細{{ selectedItem.contact || '-' }}</div>
+ <div>鐢佃瘽锛歿{ selectedItem.mobile || selectedItem.telephone || '-' }}</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>
+ <ErpSupplierSelectDialog ref="dialogRef" @selected="handleSelected" />
+</template>
diff --git a/src/views/itemreceipt/data.ts b/src/views/itemreceipt/data.ts
deleted file mode 100644
index 4864dc2..0000000
--- a/src/views/itemreceipt/data.ts
+++ /dev/null
@@ -1,527 +0,0 @@
-import type { VbenFormApi, VbenFormSchema } from '#/adapter/form';
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmArrivalNoticeApi } from '#/api/mes/wm/arrivalnotice';
-import type { MesWmArrivalNoticeLineApi } from '#/api/mes/wm/arrivalnotice/line';
-import type { MesWmItemReceiptApi } from '#/api/mes/wm/itemreceipt';
-import type { MesWmItemReceiptDetailApi } from '#/api/mes/wm/itemreceipt/detail';
-import type { MesWmItemReceiptLineApi } from '#/api/mes/wm/itemreceipt/line';
-
-import { h, markRaw } from 'vue';
-
-import {
- DICT_TYPE,
- MesAutoCodeRuleCode,
- MesWmArrivalNoticeStatusEnum,
-} from '@vben/constants';
-
-import { Button } from 'ant-design-vue';
-
-import { generateAutoCode } from '#/api/mes/md/autocode/record';
-import { getRangePickerDefaultProps } from '#/utils';
-import { MdItemSelect } from '#/views/mes/md/item/components';
-import { MdVendorSelect } from '#/views/mes/md/vendor/components';
-import {
- WmArrivalNoticeLineSelect,
- WmArrivalNoticeSelect,
-} from '#/views/wls/arrivalnotice/components';
-import {
- WmWarehouseAreaSelect,
- WmWarehouseLocationSelect,
- WmWarehouseSelect,
-} from '#/views/wls/warehouse/components';
-
-/** 琛ㄥ崟绫诲瀷 */
-export type FormType = 'create' | 'detail' | 'finish' | 'stock' | 'update';
-
-/** 琛ㄥ崟澶撮儴鏄惁鍙锛堜笂鏋躲�佽鎯呫�佸叆搴撴�侊級 */
-function isHeaderReadonly(formType: FormType): boolean {
- return formType === 'detail' || formType === 'finish' || formType === 'stock';
-}
-
-/** 鏂板/淇敼鐨勮〃鍗� */
-export function useFormSchema(
- formType: FormType,
- formApi?: VbenFormApi,
-): VbenFormSchema[] {
- return [
- {
- fieldName: 'id',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'status',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'code',
- label: '鍏ュ簱鍗曠紪鍙�',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ュ叆搴撳崟缂栧彿',
- },
- rules: 'required',
- suffix: isHeaderReadonly(formType)
- ? undefined
- : () =>
- h(
- Button,
- {
- type: 'default',
- onClick: async () => {
- const code = await generateAutoCode(
- MesAutoCodeRuleCode.WM_ITEM_RECEIPT_CODE,
- );
- await formApi?.setFieldValue('code', code);
- },
- },
- { default: () => '鐢熸垚' },
- ),
- },
- {
- fieldName: 'name',
- label: '鍏ュ簱鍗曞悕绉�',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ュ叆搴撳崟鍚嶇О',
- },
- },
- {
- fieldName: 'receiptDate',
- label: '鍏ュ簱鏃ユ湡',
- component: 'DatePicker',
- componentProps: {
- class: '!w-full',
- format: 'YYYY-MM-DD',
- placeholder: '璇烽�夋嫨鍏ュ簱鏃ユ湡',
- valueFormat: 'x',
- },
- rules: 'required',
- },
- {
- fieldName: 'noticeId',
- label: '鍒拌揣閫氱煡鍗�',
- component: markRaw(WmArrivalNoticeSelect),
- componentProps: {
- // 閫夋嫨鍒拌揣閫氱煡鍗曞悗锛岃嚜鍔ㄥ洖濉緵搴斿晢鍜岄噰璐鍗曞彿
- onChange: async (notice?: MesWmArrivalNoticeApi.ArrivalNotice) => {
- await formApi?.setValues({
- purchaseOrderCode: notice?.purchaseOrderCode,
- vendorId: notice?.vendorId,
- });
- },
- status: MesWmArrivalNoticeStatusEnum.PENDING_RECEIPT,
- },
- },
- {
- fieldName: 'vendorId',
- label: '渚涘簲鍟�',
- component: markRaw(MdVendorSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨渚涘簲鍟�',
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'purchaseOrderCode',
- label: '閲囪喘璁㈠崟鍙�',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ラ噰璐鍗曞彿',
- },
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勬悳绱㈣〃鍗� */
-export function useGridFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'code',
- label: '鍏ュ簱鍗曠紪鍙�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ュ叆搴撳崟缂栧彿',
- },
- },
- {
- fieldName: 'name',
- label: '鍏ュ簱鍗曞悕绉�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ュ叆搴撳崟鍚嶇О',
- },
- },
- {
- fieldName: 'vendorId',
- label: '渚涘簲鍟�',
- component: markRaw(MdVendorSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨渚涘簲鍟�',
- },
- },
- {
- fieldName: 'receiptDate',
- label: '鍏ュ簱鏃ユ湡',
- component: 'RangePicker',
- componentProps: {
- ...getRangePickerDefaultProps(),
- allowClear: true,
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勫瓧娈� */
-export function useGridColumns(): VxeTableGridOptions<MesWmItemReceiptApi.ItemReceipt>['columns'] {
- return [
- {
- field: 'code',
- title: '鍏ュ簱鍗曠紪鍙�',
- minWidth: 160,
- slots: { default: 'code' },
- },
- {
- field: 'name',
- title: '鍏ュ簱鍗曞悕绉�',
- minWidth: 150,
- },
- {
- field: 'purchaseOrderCode',
- title: '閲囪喘璁㈠崟鍙�',
- minWidth: 140,
- },
- {
- field: 'vendorName',
- title: '渚涘簲鍟嗗悕绉�',
- minWidth: 120,
- },
- {
- field: 'receiptDate',
- title: '鍏ュ簱鏃ユ湡',
- width: 180,
- formatter: 'formatDate',
- },
- {
- field: 'status',
- title: '鍗曟嵁鐘舵��',
- minWidth: 100,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_ITEM_RECEIPT_STATUS },
- },
- },
- {
- title: '鎿嶄綔',
- width: 240,
- fixed: 'right',
- slots: { default: 'actions' },
- },
- ];
-}
-
-/** 鍏ュ簱鍗曡瀛愯〃鐨勫瓧娈� */
-export function useLineGridColumns(
- editable: boolean,
- stockable: boolean,
-): VxeTableGridOptions<MesWmItemReceiptLineApi.ItemReceiptLine>['columns'] {
- return [
- {
- type: 'expand',
- width: 48,
- slots: { content: 'detail' },
- },
- {
- field: 'itemCode',
- title: '鐗╂枡缂栫爜',
- minWidth: 120,
- },
- {
- field: 'itemName',
- title: '鐗╂枡鍚嶇О',
- minWidth: 140,
- },
- {
- field: 'specification',
- title: '瑙勬牸鍨嬪彿',
- minWidth: 120,
- },
- {
- field: 'unitMeasureName',
- title: '鍗曚綅',
- width: 80,
- },
- {
- field: 'receivedQuantity',
- title: '鍏ュ簱鏁伴噺',
- width: 100,
- },
- {
- field: 'batchCode',
- title: '鎵规鍙�',
- minWidth: 120,
- },
- ...(editable || stockable
- ? [
- {
- title: '鎿嶄綔',
- width: 200,
- fixed: 'right',
- slots: { default: 'actions' },
- } as const,
- ]
- : []),
- ];
-}
-
-/** 鍏ュ簱鍗曡鏂板/淇敼鐨勮〃鍗� */
-export function useLineFormSchema(
- hasNotice: boolean,
- formApi?: VbenFormApi,
-): VbenFormSchema[] {
- return [
- {
- fieldName: 'noticeId',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'arrivalNoticeLineId',
- label: '鍒拌揣閫氱煡鍗曡',
- component: markRaw(WmArrivalNoticeLineSelect),
- componentProps: {
- // 閫夋嫨鍒拌揣閫氱煡鍗曡鍚庯紝鑷姩鍥炲~鐗╂枡鍜屽叆搴撴暟閲�
- onChange: async (
- line?: MesWmArrivalNoticeLineApi.ArrivalNoticeLine,
- ) => {
- await formApi?.setValues({
- itemId: line?.itemId,
- receivedQuantity: line?.arrivalQuantity,
- });
- },
- },
- dependencies: {
- triggerFields: ['noticeId'],
- if: () => hasNotice,
- componentProps: (values) => ({
- noticeId: values.noticeId,
- }),
- },
- },
- {
- fieldName: 'itemId',
- label: '鐗╂枡',
- component: markRaw(MdItemSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨鐗╂枡',
- },
- rules: 'selectRequired',
- dependencies: {
- triggerFields: ['arrivalNoticeLineId'],
- componentProps: (values) => ({
- disabled: !!values.arrivalNoticeLineId,
- placeholder: '璇烽�夋嫨鐗╂枡',
- }),
- },
- },
- {
- fieldName: 'receivedQuantity',
- label: '鍏ュ簱鏁伴噺',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0,
- placeholder: '璇疯緭鍏ュ叆搴撴暟閲�',
- precision: 2,
- },
- rules: 'required',
- },
- {
- fieldName: 'productionDate',
- label: '鐢熶骇鏃ユ湡',
- component: 'DatePicker',
- componentProps: {
- class: '!w-full',
- format: 'YYYY-MM-DD',
- placeholder: '璇烽�夋嫨鐢熶骇鏃ユ湡',
- valueFormat: 'x',
- },
- },
- {
- fieldName: 'expireDate',
- label: '鏈夋晥鏈�',
- component: 'DatePicker',
- componentProps: {
- class: '!w-full',
- format: 'YYYY-MM-DD',
- placeholder: '璇烽�夋嫨鏈夋晥鏈�',
- valueFormat: 'x',
- },
- },
- {
- fieldName: 'lotNumber',
- label: '鐢熶骇鎵瑰彿',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ョ敓浜ф壒鍙�',
- },
- },
- {
- fieldName: 'batchCode',
- label: '鎵规鍙�',
- component: 'Input',
- componentProps: {
- disabled: true,
- placeholder: '鐢卞~鍐欎俊鎭嚜鍔ㄧ敓鎴�',
- },
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
-
-/** 涓婃灦鏄庣粏瀛愯〃鐨勫瓧娈� */
-export function useDetailGridColumns(
- stockable: boolean,
-): VxeTableGridOptions<MesWmItemReceiptDetailApi.ItemReceiptDetail>['columns'] {
- return [
- {
- field: 'warehouseName',
- title: '浠撳簱鍚嶇О',
- minWidth: 100,
- },
- {
- field: 'locationName',
- title: '搴撳尯鍚嶇О',
- minWidth: 100,
- },
- {
- field: 'areaName',
- title: '搴撲綅鍚嶇О',
- minWidth: 100,
- },
- {
- field: 'quantity',
- title: '鏁伴噺',
- width: 100,
- },
- ...(stockable
- ? [
- {
- title: '鎿嶄綔',
- width: 120,
- fixed: 'right',
- slots: { default: 'actions' },
- } as const,
- ]
- : []),
- ];
-}
-
-/** 涓婃灦鏄庣粏鏂板/淇敼鐨勮〃鍗� */
-export function useDetailFormSchema(formApi?: VbenFormApi): VbenFormSchema[] {
- return [
- {
- fieldName: 'itemId',
- label: '鐗╂枡',
- component: markRaw(MdItemSelect),
- componentProps: {
- disabled: true,
- },
- },
- {
- fieldName: 'warehouseId',
- label: '鍏ュ簱浠撳簱',
- component: markRaw(WmWarehouseSelect),
- componentProps: {
- // 鍒囨崲浠撳簱鍚庢竻绌哄簱鍖哄拰搴撲綅
- onChange: async () => {
- await formApi?.setValues({
- areaId: undefined,
- locationId: undefined,
- });
- },
- placeholder: '璇烽�夋嫨浠撳簱',
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'locationId',
- label: '搴撳尯',
- component: markRaw(WmWarehouseLocationSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨搴撳尯',
- },
- rules: 'selectRequired',
- dependencies: {
- triggerFields: ['warehouseId'],
- componentProps: (values) => ({
- // 鍒囨崲搴撳尯鍚庢竻绌哄簱浣�
- onChange: async () => {
- await formApi?.setFieldValue('areaId', undefined);
- },
- placeholder: '璇烽�夋嫨搴撳尯',
- warehouseId: values.warehouseId,
- }),
- },
- },
- {
- fieldName: 'areaId',
- label: '搴撲綅',
- component: markRaw(WmWarehouseAreaSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨搴撲綅',
- },
- rules: 'selectRequired',
- dependencies: {
- triggerFields: ['locationId'],
- componentProps: (values) => ({
- locationId: values.locationId,
- placeholder: '璇烽�夋嫨搴撲綅',
- }),
- },
- },
- {
- fieldName: 'quantity',
- label: '鏁伴噺',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0,
- placeholder: '璇疯緭鍏ユ暟閲�',
- precision: 2,
- },
- rules: 'required',
- },
- ];
-}
diff --git a/src/views/itemreceipt/index.vue b/src/views/itemreceipt/index.vue
deleted file mode 100644
index a4a4132..0000000
--- a/src/views/itemreceipt/index.vue
+++ /dev/null
@@ -1,201 +0,0 @@
-<script lang="ts" setup>
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmItemReceiptApi } from '#/api/mes/wm/itemreceipt';
-
-import { Page, useVbenModal } from '@vben/common-ui';
-import { MesWmItemReceiptStatusEnum } from '@vben/constants';
-import { downloadFileFromBlobPart } from '@vben/utils';
-
-import { Button, message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import {
- cancelItemReceipt,
- deleteItemReceipt,
- exportItemReceipt,
- getItemReceiptPage,
-} from '#/api/mes/wm/itemreceipt';
-import { $t } from '#/locales';
-
-import { useGridColumns, useGridFormSchema } from './data';
-import Form from './modules/form.vue';
-
-const [FormModal, formModalApi] = useVbenModal({
- connectedComponent: Form,
- destroyOnClose: true,
-});
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- gridApi.query();
-}
-
-/** 鍒涘缓閲囪喘鍏ュ簱鍗� */
-function handleCreate() {
- formModalApi.setData({ formType: 'create' }).open();
-}
-
-/** 鏌ョ湅閲囪喘鍏ュ簱鍗� */
-function handleDetail(row: MesWmItemReceiptApi.ItemReceipt) {
- formModalApi.setData({ formType: 'detail', id: row.id }).open();
-}
-
-/** 缂栬緫閲囪喘鍏ュ簱鍗� */
-function handleEdit(row: MesWmItemReceiptApi.ItemReceipt) {
- formModalApi.setData({ formType: 'update', id: row.id }).open();
-}
-
-/** 鎵ц涓婃灦 */
-function handleStock(row: MesWmItemReceiptApi.ItemReceipt) {
- formModalApi.setData({ formType: 'stock', id: row.id }).open();
-}
-
-/** 鎵ц鍏ュ簱 */
-function handleFinish(row: MesWmItemReceiptApi.ItemReceipt) {
- formModalApi.setData({ formType: 'finish', id: row.id }).open();
-}
-
-/** 鍒犻櫎閲囪喘鍏ュ簱鍗� */
-async function handleDelete(row: MesWmItemReceiptApi.ItemReceipt) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.code]),
- duration: 0,
- });
- try {
- await deleteItemReceipt(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.code]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-/** 鍙栨秷閲囪喘鍏ュ簱鍗� */
-async function handleCancel(row: MesWmItemReceiptApi.ItemReceipt) {
- await cancelItemReceipt(row.id!);
- message.success('鍙栨秷鎴愬姛');
- handleRefresh();
-}
-
-/** 瀵煎嚭琛ㄦ牸 */
-async function handleExport() {
- const data = await exportItemReceipt(await gridApi.formApi.getValues());
- downloadFileFromBlobPart({ fileName: '閲囪喘鍏ュ簱鍗�.xls', source: data });
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- formOptions: {
- schema: useGridFormSchema(),
- },
- gridOptions: {
- columns: useGridColumns(),
- height: 'auto',
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }, formValues) => {
- return await getItemReceiptPage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- ...formValues,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- search: true,
- },
- } as VxeTableGridOptions<MesWmItemReceiptApi.ItemReceipt>,
-});
-</script>
-
-<template>
- <Page auto-content-height><FormModal @success="handleRefresh" />
-
- <Grid table-title="閲囪喘鍏ュ簱鍗曞垪琛�">
- <template #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: $t('ui.actionTitle.create', ['閲囪喘鍏ュ簱鍗�']),
- type: 'primary',
- icon: ACTION_ICON.ADD,
- auth: ['mes:wm-item-receipt:create'],
- onClick: handleCreate,
- },
- {
- label: $t('ui.actionTitle.export'),
- type: 'primary',
- icon: ACTION_ICON.DOWNLOAD,
- auth: ['mes:wm-item-receipt:export'],
- onClick: handleExport,
- },
- ]"
- />
- </template>
- <template #code="{ row }">
- <Button type="link" @click="handleDetail(row)">
- {{ row.code }}
- </Button>
- </template>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- auth: ['mes:wm-item-receipt:update'],
- ifShow: row.status === MesWmItemReceiptStatusEnum.PREPARE,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- auth: ['mes:wm-item-receipt:delete'],
- ifShow: row.status === MesWmItemReceiptStatusEnum.PREPARE,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.code]),
- confirm: handleDelete.bind(null, row),
- },
- },
- {
- label: '鎵ц涓婃灦',
- type: 'link',
- auth: ['mes:wm-item-receipt:update'],
- ifShow: row.status === MesWmItemReceiptStatusEnum.APPROVING,
- onClick: handleStock.bind(null, row),
- },
- {
- label: '鎵ц鍏ュ簱',
- type: 'link',
- auth: ['mes:wm-item-receipt:finish'],
- ifShow: row.status === MesWmItemReceiptStatusEnum.APPROVED,
- onClick: handleFinish.bind(null, row),
- },
- {
- label: '鍙栨秷',
- type: 'link',
- danger: true,
- auth: ['mes:wm-item-receipt:update'],
- ifShow:
- row.status === MesWmItemReceiptStatusEnum.APPROVING ||
- row.status === MesWmItemReceiptStatusEnum.APPROVED,
- popConfirm: {
- title: '纭鍙栨秷璇ラ噰璐叆搴撳崟锛熷彇娑堝悗涓嶅彲鎭㈠銆�',
- confirm: handleCancel.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </Page>
-</template>
diff --git a/src/views/itemreceipt/modules/detail-form.vue b/src/views/itemreceipt/modules/detail-form.vue
deleted file mode 100644
index c80e787..0000000
--- a/src/views/itemreceipt/modules/detail-form.vue
+++ /dev/null
@@ -1,104 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmItemReceiptDetailApi } from '#/api/mes/wm/itemreceipt/detail';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createItemReceiptDetail,
- getItemReceiptDetail,
- updateItemReceiptDetail,
-} from '#/api/mes/wm/itemreceipt/detail';
-import { $t } from '#/locales';
-
-import { useDetailFormSchema } from '../data';
-
-const emit = defineEmits<{ success: [lineId: number] }>();
-const formData = ref<MesWmItemReceiptDetailApi.ItemReceiptDetail>();
-const receiptId = ref<number>(); // 鎵�灞炲叆搴撳崟缂栧彿
-const lineId = ref<number>(); // 鎵�灞炲叆搴撳崟琛岀紪鍙�
-
-const getTitle = computed(() => {
- return formData.value?.id
- ? $t('ui.actionTitle.edit', ['涓婃灦鏄庣粏'])
- : $t('ui.actionTitle.create', ['涓婃灦鏄庣粏']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 90,
- },
- layout: 'horizontal',
- schema: useDetailFormSchema(),
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data =
- (await formApi.getValues()) as MesWmItemReceiptDetailApi.ItemReceiptDetail;
- data.receiptId = receiptId.value;
- data.lineId = lineId.value;
- try {
- await (formData.value?.id
- ? updateItemReceiptDetail({ ...data, id: formData.value.id })
- : createItemReceiptDetail(data));
- // 鍏抽棴骞舵彁绀�
- await modalApi.close();
- emit('success', lineId.value!);
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- return;
- }
- formApi.setState({ schema: useDetailFormSchema(formApi) });
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{
- detailId?: number;
- itemId?: number;
- lineId: number;
- receiptId: number;
- }>();
- receiptId.value = data.receiptId;
- lineId.value = data.lineId;
- if (data.detailId) {
- modalApi.lock();
- try {
- formData.value = await getItemReceiptDetail(data.detailId);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- } else if (data.itemId) {
- await formApi.setFieldValue('itemId', data.itemId);
- }
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- </Modal>
-</template>
diff --git a/src/views/itemreceipt/modules/detail-list.vue b/src/views/itemreceipt/modules/detail-list.vue
deleted file mode 100644
index 57a89ac..0000000
--- a/src/views/itemreceipt/modules/detail-list.vue
+++ /dev/null
@@ -1,103 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmItemReceiptDetailApi } from '#/api/mes/wm/itemreceipt/detail';
-
-import { computed, watch } from 'vue';
-
-import { message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import { deleteItemReceiptDetail } from '#/api/mes/wm/itemreceipt/detail';
-import { $t } from '#/locales';
-
-import { useDetailGridColumns } from '../data';
-
-const props = defineProps<{
- details: MesWmItemReceiptDetailApi.ItemReceiptDetail[];
- formType: FormType;
-}>();
-
-const emit = defineEmits<{
- edit: [detailId: number];
- refresh: [];
-}>();
-
-const isStock = computed(() => props.formType === 'stock'); // 鏄惁涓轰笂鏋舵ā寮�
-
-/** 缂栬緫涓婃灦鏄庣粏 */
-function handleEdit(row: MesWmItemReceiptDetailApi.ItemReceiptDetail) {
- emit('edit', row.id!);
-}
-
-/** 鍒犻櫎涓婃灦鏄庣粏 */
-async function handleDelete(row: MesWmItemReceiptDetailApi.ItemReceiptDetail) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.warehouseName]),
- duration: 0,
- });
- try {
- await deleteItemReceiptDetail(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.warehouseName]));
- emit('refresh');
- } finally {
- hideLoading();
- }
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- gridOptions: {
- border: true,
- columns: useDetailGridColumns(isStock.value),
- data: props.details,
- pagerConfig: {
- enabled: false,
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- size: 'small',
- toolbarConfig: {
- enabled: false,
- },
- } as VxeTableGridOptions<MesWmItemReceiptDetailApi.ItemReceiptDetail>,
-});
-
-watch(
- () => props.details,
- (details) => gridApi.setGridOptions({ data: details }),
-);
-</script>
-
-<template>
- <div class="px-4 py-2">
- <Grid>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [
- row.warehouseName,
- ]),
- confirm: handleDelete.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </div>
-</template>
diff --git a/src/views/itemreceipt/modules/form.vue b/src/views/itemreceipt/modules/form.vue
deleted file mode 100644
index 1c9b1e2..0000000
--- a/src/views/itemreceipt/modules/form.vue
+++ /dev/null
@@ -1,242 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { MesWmItemReceiptApi } from '#/api/mes/wm/itemreceipt';
-
-import { computed, ref } from 'vue';
-
-import { confirm, useVbenModal } from '@vben/common-ui';
-import { MesWmItemReceiptStatusEnum } from '@vben/constants';
-
-import { Button, Divider, message, Popconfirm } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createItemReceipt,
- finishItemReceipt,
- getItemReceipt,
- stockItemReceipt,
- submitItemReceipt,
- updateItemReceipt,
-} from '#/api/mes/wm/itemreceipt';
-import { $t } from '#/locales';
-
-import { useFormSchema } from '../data';
-import LineList from './line-list.vue';
-
-const emit = defineEmits(['success']);
-const formType = ref<FormType>('create');
-const formData = ref<MesWmItemReceiptApi.ItemReceipt>();
-const originalSnapshot = ref(''); // 琛ㄥ崟鍘熷鏁版嵁蹇収锛岀敤浜庢彁浜ゆ椂璺宠繃鏈彉鏇寸殑淇濆瓨璇锋眰
-const isEditable = computed(() =>
- // 鏄惁涓虹紪杈戞ā寮忥紙鍙繚瀛橈級
- ['create', 'update'].includes(formType.value),
-);
-const isStock = computed(() => formType.value === 'stock'); // 鏄惁涓轰笂鏋舵ā寮�
-const isFinish = computed(() => formType.value === 'finish'); // 鏄惁涓烘墽琛屽叆搴撴ā寮�
-const canSubmit = computed(
- () =>
- // 鏄惁鍙彁浜�
- formType.value === 'update' &&
- formData.value?.status === MesWmItemReceiptStatusEnum.PREPARE,
-);
-const getTitle = computed(() => {
- if (formType.value === 'detail') {
- return $t('ui.actionTitle.view', ['閲囪喘鍏ュ簱鍗�']);
- }
- if (formType.value === 'stock') {
- return '鎵ц涓婃灦';
- }
- if (formType.value === 'finish') {
- return '鎵ц鍏ュ簱';
- }
- return formType.value === 'update'
- ? $t('ui.actionTitle.edit', ['閲囪喘鍏ュ簱鍗�'])
- : $t('ui.actionTitle.create', ['閲囪喘鍏ュ簱鍗�']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 110,
- },
- layout: 'horizontal',
- schema: [],
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-/** 鎻愪氦鍏ュ簱鍗曪細琛ㄥ崟鏈変慨鏀规椂鍏堜繚瀛橈紝鍐嶈皟鐢ㄦ彁浜ゆ帴鍙� */
-async function handleSubmit() {
- const { valid } = await formApi.validate();
- if (!valid || !formData.value?.id) {
- return;
- }
- modalApi.lock();
- try {
- const current = JSON.stringify(await formApi.getValues());
- if (current !== originalSnapshot.value) {
- const data =
- (await formApi.getValues()) as MesWmItemReceiptApi.ItemReceipt;
- await updateItemReceipt({ ...formData.value, ...data });
- originalSnapshot.value = current;
- }
- await submitItemReceipt(formData.value.id);
- message.success('鎻愪氦鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-/** 鎵ц涓婃灦 */
-async function handleStock() {
- if (!formData.value?.id) {
- return;
- }
- modalApi.lock();
- try {
- await stockItemReceipt(formData.value.id);
- message.success('涓婃灦鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-/** 鎵ц鍏ュ簱 */
-async function handleFinish() {
- if (!formData.value?.id) {
- return;
- }
- modalApi.lock();
- try {
- await finishItemReceipt(formData.value.id);
- message.success('鍏ュ簱鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- if (!isEditable.value) {
- await modalApi.close();
- return;
- }
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data = (await formApi.getValues()) as MesWmItemReceiptApi.ItemReceipt;
- try {
- if (formData.value?.id) {
- await updateItemReceipt({ ...formData.value, ...data });
- formData.value = { ...formData.value, ...data };
- } else {
- const id = await createItemReceipt(data);
- formData.value = {
- ...data,
- id,
- status: MesWmItemReceiptStatusEnum.PREPARE,
- };
- await formApi.setFieldValue('id', id);
- await formApi.setFieldValue('status', formData.value.status);
- formType.value = 'update';
- }
- originalSnapshot.value = JSON.stringify(await formApi.getValues());
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- originalSnapshot.value = '';
- return;
- }
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{ formType: FormType; id?: number }>();
- formType.value = data.formType;
- formApi.setState({ schema: useFormSchema(formType.value, formApi) });
- formApi.setDisabled(!isEditable.value);
- modalApi.setState({ showConfirmButton: isEditable.value });
- if (data?.id) {
- modalApi.lock();
- try {
- formData.value = await getItemReceipt(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- }
- originalSnapshot.value = JSON.stringify(await formApi.getValues());
- },
-});
-
-/** 涓婃灦鍓嶇‘璁� */
-async function confirmStock() {
- try {
- await confirm('纭鎵ц涓婃灦锛�');
- } catch {
- return;
- }
- await handleStock();
-}
-
-/** 鍏ュ簱鍓嶇‘璁� */
-async function confirmFinish() {
- try {
- await confirm('纭鎵ц鍏ュ簱锛熸墽琛屽悗灏嗘洿鏂板簱瀛樺彴璐︺��');
- } catch {
- return;
- }
- await handleFinish();
-}
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- <!-- 闈炴柊寤烘ā寮忓睍绀虹墿鏂欎俊鎭� -->
- <template v-if="formData?.id">
- <Divider>鐗╂枡淇℃伅</Divider>
- <div class="mx-4">
- <LineList
- :form-type="formType"
- :notice-id="formData.noticeId"
- :receipt-id="formData.id"
- />
- </div>
- </template>
- <template #prepend-footer>
- <div class="flex flex-auto items-center gap-2">
- <Popconfirm
- v-if="canSubmit"
- title="纭鎻愪氦璇ラ噰璐叆搴撳崟锛熴�愭彁浜ゅ悗灏嗕笉鑳戒慨鏀广��"
- @confirm="handleSubmit"
- >
- <Button type="primary">鎻愪氦</Button>
- </Popconfirm>
- <Button v-if="isStock" type="primary" @click="confirmStock">
- 鎵ц涓婃灦
- </Button>
- <Button v-if="isFinish" type="primary" @click="confirmFinish">
- 鎵ц鍏ュ簱
- </Button>
- </div>
- </template>
- </Modal>
-</template>
diff --git a/src/views/itemreceipt/modules/line-form.vue b/src/views/itemreceipt/modules/line-form.vue
deleted file mode 100644
index debfc76..0000000
--- a/src/views/itemreceipt/modules/line-form.vue
+++ /dev/null
@@ -1,104 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmItemReceiptLineApi } from '#/api/mes/wm/itemreceipt/line';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createItemReceiptLine,
- getItemReceiptLine,
- updateItemReceiptLine,
-} from '#/api/mes/wm/itemreceipt/line';
-import { $t } from '#/locales';
-
-import { useLineFormSchema } from '../data';
-
-const emit = defineEmits(['success']);
-const formData = ref<MesWmItemReceiptLineApi.ItemReceiptLine>();
-const receiptId = ref<number>(); // 鎵�灞炲叆搴撳崟缂栧彿
-const noticeId = ref<number>(); // 鎵�灞炲埌璐ч�氱煡鍗曠紪鍙�
-
-const getTitle = computed(() => {
- return formData.value?.id
- ? $t('ui.actionTitle.edit', ['鐗╂枡鍏ュ簱鍗曡'])
- : $t('ui.actionTitle.create', ['鐗╂枡鍏ュ簱鍗曡']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 110,
- },
- layout: 'horizontal',
- schema: [],
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data =
- (await formApi.getValues()) as MesWmItemReceiptLineApi.ItemReceiptLine;
- data.receiptId = receiptId.value;
- try {
- await (formData.value?.id
- ? updateItemReceiptLine({ ...data, id: formData.value.id })
- : createItemReceiptLine(data));
- // 鍏抽棴骞舵彁绀�
- await modalApi.close();
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- return;
- }
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{
- id?: number;
- noticeId?: number;
- receiptId: number;
- }>();
- receiptId.value = data.receiptId;
- noticeId.value = data.noticeId;
- formApi.setState({ schema: useLineFormSchema(!!data.noticeId, formApi) });
- if (data.noticeId) {
- await formApi.setFieldValue('noticeId', data.noticeId);
- }
- if (!data.id) {
- return;
- }
- modalApi.lock();
- try {
- formData.value = await getItemReceiptLine(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues({ ...formData.value, noticeId: noticeId.value });
- } finally {
- modalApi.unlock();
- }
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- </Modal>
-</template>
diff --git a/src/views/itemreceipt/modules/line-list.vue b/src/views/itemreceipt/modules/line-list.vue
deleted file mode 100644
index 2e5a09b..0000000
--- a/src/views/itemreceipt/modules/line-list.vue
+++ /dev/null
@@ -1,241 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmItemReceiptDetailApi } from '#/api/mes/wm/itemreceipt/detail';
-import type { MesWmItemReceiptLineApi } from '#/api/mes/wm/itemreceipt/line';
-
-import { computed, reactive } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import { getItemReceiptDetailListByLineId } from '#/api/mes/wm/itemreceipt/detail';
-import {
- deleteItemReceiptLine,
- getItemReceiptLinePage,
-} from '#/api/mes/wm/itemreceipt/line';
-import { $t } from '#/locales';
-import { PrinterLabel } from '#/views/wls/barcode/components';
-
-import { useLineGridColumns } from '../data';
-import DetailForm from './detail-form.vue';
-import DetailList from './detail-list.vue';
-import LineForm from './line-form.vue';
-
-const props = defineProps<{
- formType: FormType;
- noticeId?: number;
- receiptId: number;
-}>();
-
-const isEditable = computed(() =>
- // 鏄惁鍙紪杈戞槑缁嗚
- ['create', 'update'].includes(props.formType),
-);
-const isStock = computed(() => props.formType === 'stock'); // 鏄惁涓轰笂鏋舵ā寮�
-const detailMap = reactive<
- Record<number, MesWmItemReceiptDetailApi.ItemReceiptDetail[]>
->({}); // 宸插睍寮�琛岀殑涓婃灦鏄庣粏缂撳瓨
-
-const [LineFormModal, lineFormModalApi] = useVbenModal({
- connectedComponent: LineForm,
- destroyOnClose: true,
-});
-
-const [DetailFormModal, detailFormModalApi] = useVbenModal({
- connectedComponent: DetailForm,
- destroyOnClose: true,
-});
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- for (const id of Object.keys(detailMap)) {
- delete detailMap[Number(id)];
- }
- gridApi.query();
-}
-
-/** 娣诲姞鐗╂枡 */
-function handleCreate() {
- lineFormModalApi
- .setData({ noticeId: props.noticeId, receiptId: props.receiptId })
- .open();
-}
-
-/** 缂栬緫鐗╂枡 */
-function handleEdit(row: MesWmItemReceiptLineApi.ItemReceiptLine) {
- lineFormModalApi
- .setData({
- id: row.id,
- noticeId: props.noticeId,
- receiptId: props.receiptId,
- })
- .open();
-}
-
-/** 鍒犻櫎鐗╂枡 */
-async function handleDelete(row: MesWmItemReceiptLineApi.ItemReceiptLine) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.itemName]),
- duration: 0,
- });
- try {
- await deleteItemReceiptLine(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.itemName]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-/** 涓婃灦锛氱洿鎺ユ墦寮�鏄庣粏鍒涘缓琛ㄥ崟 */
-function handleStock(row: MesWmItemReceiptLineApi.ItemReceiptLine) {
- openDetailForm(row.id!, row.itemId);
-}
-
-/** 鎵撳紑涓婃灦鏄庣粏琛ㄥ崟 */
-function openDetailForm(lineId: number, itemId?: number, detailId?: number) {
- detailFormModalApi
- .setData({ detailId, itemId, lineId, receiptId: props.receiptId })
- .open();
-}
-
-/** 鑾峰彇宸插睍寮�琛岀殑涓婃灦鏄庣粏 */
-function getExpandedDetails(row: MesWmItemReceiptLineApi.ItemReceiptLine) {
- return detailMap[row.id!] || [];
-}
-
-/** 鍔犺浇鎸囧畾琛岀殑涓婃灦鏄庣粏 */
-async function loadLineDetails(lineId: number) {
- detailMap[lineId] = await getItemReceiptDetailListByLineId(lineId);
-}
-
-/** 灞曞紑琛屾椂鎳掑姞杞戒笂鏋舵槑缁� */
-async function handleExpandChange(
- row: MesWmItemReceiptLineApi.ItemReceiptLine,
- expanded: boolean,
-) {
- if (!expanded) {
- return;
- }
- await loadLineDetails(row.id!);
-}
-
-/** 鏄庣粏琛ㄥ崟鎻愪氦鎴愬姛鍚庯紝鍒锋柊瀵瑰簲琛屽凡灞曞紑鐨勬槑缁� */
-async function handleDetailSuccess(lineId: number) {
- await loadLineDetails(lineId);
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- gridOptions: {
- columns: useLineGridColumns(isEditable.value, isStock.value),
- expandConfig: {
- padding: true,
- },
- height: 400,
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }) => {
- if (!props.receiptId) {
- return { list: [], total: 0 };
- }
- return await getItemReceiptLinePage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- receiptId: props.receiptId,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- },
- } as VxeTableGridOptions<MesWmItemReceiptLineApi.ItemReceiptLine>,
- gridEvents: {
- toggleRowExpand: ({
- expanded,
- row,
- }: {
- expanded: boolean;
- row: MesWmItemReceiptLineApi.ItemReceiptLine;
- }) => {
- handleExpandChange(row, expanded);
- },
- },
-});
-</script>
-
-<template>
- <div>
- <LineFormModal @success="handleRefresh" />
- <DetailFormModal @success="handleDetailSuccess" />
- <Grid table-title="鐗╂枡淇℃伅">
- <template v-if="isEditable" #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: '娣诲姞鐗╂枡',
- type: 'primary',
- icon: ACTION_ICON.ADD,
- onClick: handleCreate,
- },
- ]"
- />
- </template>
- <template #detail="{ row }">
- <DetailList
- :details="getExpandedDetails(row)"
- :form-type="formType"
- @edit="(detailId) => openDetailForm(row.id!, row.itemId, detailId)"
- @refresh="loadLineDetails(row.id!)"
- />
- </template>
- <template #actions="{ row }">
- <div class="flex items-center justify-center">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- ifShow: isEditable,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- ifShow: isEditable,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.itemName]),
- confirm: handleDelete.bind(null, row),
- },
- },
- {
- label: '涓婃灦',
- type: 'link',
- ifShow: isStock,
- onClick: handleStock.bind(null, row),
- },
- ]"
- />
- <PrinterLabel
- v-if="isStock"
- :biz-code="row.batchCode"
- :biz-id="row.batchId"
- biz-type="ITEM_BATCH"
- />
- </div>
- </template>
- </Grid>
- </div>
-</template>
diff --git a/src/views/materialstock/components/index.ts b/src/views/materialstock/components/index.ts
deleted file mode 100644
index aa23039..0000000
--- a/src/views/materialstock/components/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export { default as WmMaterialStockSelectDialog } from './select-dialog.vue';
-export { default as WmMaterialStockSelect } from './select.vue';
diff --git a/src/views/materialstock/components/select-dialog.vue b/src/views/materialstock/components/select-dialog.vue
deleted file mode 100644
index 6e0de0e..0000000
--- a/src/views/materialstock/components/select-dialog.vue
+++ /dev/null
@@ -1,268 +0,0 @@
-<script lang="ts" setup>
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmMaterialStockApi } from '#/api/mes/wm/materialstock';
-
-import { computed, nextTick, ref } from 'vue';
-
-import { Alert, message, Modal } from 'ant-design-vue';
-
-import { useVbenVxeGrid } from '#/adapter/vxe-table';
-import { getMaterialStockPage } from '#/api/mes/wm/materialstock';
-import { MdItemTypeTree } from '#/views/mes/md/item/type/components';
-
-import { useSelectGridColumns, useSelectGridFormSchema } from '../data';
-
-/** 铏氭嫙浠撹繃婊ゆā寮忥細'exclude' 鎺掗櫎铏氭嫙浠擄紙榛樿锛夛紝'only' 鍙湅铏氭嫙浠擄紝'all' 涓嶈繃婊� */
-type VirtualFilter = 'all' | 'exclude' | 'only';
-
-const props = withDefaults(
- defineProps<{
- batchId?: number;
- itemId?: number;
- virtualFilter?: VirtualFilter;
- warehouseId?: number;
- }>(),
- {
- batchId: undefined,
- itemId: undefined,
- virtualFilter: 'exclude',
- warehouseId: undefined,
- },
-);
-
-const emit = defineEmits<{
- selected: [rows: MesWmMaterialStockApi.MaterialStock[]];
-}>();
-
-const open = ref(false);
-const multiple = ref(false); // 鏄惁澶氶�夛紱榛樿鎸夊崟閫夐�夋嫨鍣ㄤ娇鐢�
-const selectedRows = ref<MesWmMaterialStockApi.MaterialStock[]>([]);
-const preSelectedIds = ref<number[]>([]);
-const searchItemTypeId = ref<number>();
-
-/** 褰撳墠 props 鏄惁甯﹂杩囨护 */
-const showAlert = computed(
- () =>
- props.batchId !== null ||
- props.warehouseId !== null ||
- props.virtualFilter === 'only',
-);
-
-/** 棰勮繃婊ゆ彁绀烘枃瀛� */
-const alertTitle = computed(() => {
- const parts: string[] = [];
- if (props.batchId !== null) {
- parts.push('鎵规');
- }
- if (props.warehouseId !== null) {
- parts.push('浠撳簱');
- }
- if (props.virtualFilter === 'only') {
- parts.push('鍙湅铏氭嫙浠�');
- }
- return `宸叉寜${parts.join('/')}棰勮繃婊;
-});
-
-/** 鑾峰彇澶氶�夎褰曪紝鍖呭惈 VXE reserve 璺ㄩ〉璁板綍 */
-function getMultipleSelectedRows() {
- const selectedMap = new Map<number, MesWmMaterialStockApi.MaterialStock>();
- const records = [
- ...(gridApi.grid.getCheckboxReserveRecords?.() ?? []),
- ...(gridApi.grid.getCheckboxRecords?.() ?? []),
- ] as MesWmMaterialStockApi.MaterialStock[];
- records.forEach((row) => {
- const rowId = row.id;
- if (rowId !== undefined) {
- selectedMap.set(rowId, row);
- }
- });
- return [...selectedMap.values()];
-}
-
-/** 澶勭悊澶氶�夊嬀閫夊彉鍖� */
-function handleCheckboxSelectChange() {
- selectedRows.value = getMultipleSelectedRows();
-}
-
-/** 澶勭悊鍗曢�夊垏鎹� */
-function handleRadioChange(row: MesWmMaterialStockApi.MaterialStock) {
- selectedRows.value = [row];
-}
-
-/** 澶氶�夋ā寮忎笅鍒囨崲琛屽嬀閫� */
-async function toggleMultipleRow(row: MesWmMaterialStockApi.MaterialStock) {
- const selected = gridApi.grid.isCheckedByCheckboxRow(row);
- await gridApi.grid.setCheckboxRow(row, !selected);
- selectedRows.value = getMultipleSelectedRows();
-}
-
-/** 鍙屽嚮琛岋細鍗曢�夌洿鎺ョ‘璁わ紱澶氶�夊垏鎹㈠嬀閫� */
-async function handleRowDblclick({
- row,
-}: {
- row: MesWmMaterialStockApi.MaterialStock;
-}) {
- if (multiple.value) {
- await toggleMultipleRow(row);
- return;
- }
- selectedRows.value = [row];
- await gridApi.grid.setRadioRow(row);
- handleConfirm();
-}
-
-/** 鍥炴樉棰勯�� */
-async function applyPreSelection() {
- if (preSelectedIds.value.length === 0) {
- return;
- }
- const rows = gridApi.grid.getData() as MesWmMaterialStockApi.MaterialStock[];
- for (const row of rows) {
- if (
- row.id === undefined ||
- row.id === null ||
- !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();
- }
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- formOptions: {
- schema: useSelectGridFormSchema(),
- },
- gridOptions: {
- columns: useSelectGridColumns(false),
- height: 480,
- keepSource: true,
- checkboxConfig: { highlight: true, range: true, reserve: true },
- radioConfig: { highlight: true, trigger: 'row' },
- proxyConfig: {
- ajax: {
- query: async ({ page }, formValues) => {
- return await getMaterialStockPage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- ...formValues,
- batchId: props.batchId,
- // 榛樿鏌ユ湭鍐荤粨
- frozen: false,
- itemTypeId: searchItemTypeId.value,
- itemId: formValues.itemId ?? props.itemId,
- warehouseId: formValues.warehouseId ?? props.warehouseId,
- virtualFilter:
- props.virtualFilter === 'all' ? undefined : props.virtualFilter,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- search: true,
- },
- } as VxeTableGridOptions<MesWmMaterialStockApi.MaterialStock>,
- gridEvents: {
- cellDblclick: handleRowDblclick,
- checkboxAll: handleCheckboxSelectChange,
- checkboxChange: handleCheckboxSelectChange,
- radioChange: ({ row }: { row: MesWmMaterialStockApi.MaterialStock }) => {
- handleRadioChange(row);
- },
- },
-});
-
-/** 鐗╂枡鍒嗙被鏍戣妭鐐圭偣鍑� */
-function handleTypeNodeClick(row: undefined | { id?: number }) {
- searchItemTypeId.value = row?.id;
- gridApi.query();
-}
-
-/** 閲嶇疆鏌ヨ鍜岄�夋嫨鐘舵�� */
-async function resetQueryState() {
- selectedRows.value = [];
- searchItemTypeId.value = undefined;
- await gridApi.grid.clearCheckboxRow();
- await gridApi.grid.clearCheckboxReserve();
- await gridApi.grid.clearRadioRow();
- await gridApi.formApi.resetForm();
-}
-
-/** 鎵撳紑寮圭獥 */
-async function openModal(
- selectedIds?: number[],
- options?: { multiple?: boolean },
-) {
- open.value = true;
- multiple.value = options?.multiple ?? false;
- preSelectedIds.value = selectedIds || [];
- await nextTick();
- gridApi.setGridOptions({
- columns: useSelectGridColumns(multiple.value),
- });
- await resetQueryState();
- await gridApi.query();
- await nextTick();
- await applyPreSelection();
-}
-
-/** 鍏抽棴寮圭獥 */
-async function closeModal() {
- open.value = false;
- await resetQueryState();
-}
-
-/** 纭閫夋嫨 */
-function handleConfirm() {
- const rows = multiple.value ? getMultipleSelectedRows() : selectedRows.value;
- if (rows.length === 0) {
- message.warning(multiple.value ? '璇疯嚦灏戦�夋嫨涓�鏉℃暟鎹�' : '璇烽�夋嫨涓�鏉℃暟鎹�');
- return;
- }
- emit('selected', multiple.value ? rows : [rows[0]!]);
- open.value = false;
-}
-
-defineExpose({ open: openModal });
-</script>
-
-<template>
- <Modal
- v-model:open="open"
- :destroy-on-close="true"
- title="搴撳瓨鐗╄祫閫夋嫨"
- width="80%"
- @cancel="closeModal"
- @ok="handleConfirm"
- >
- <Alert
- v-if="showAlert"
- class="mb-3"
- :message="alertTitle"
- show-icon
- type="info"
- />
- <div class="flex gap-3">
- <div class="bg-card w-1/6 rounded p-2">
- <MdItemTypeTree @node-click="handleTypeNodeClick" />
- </div>
- <div class="w-5/6">
- <Grid table-title="搴撳瓨鍒楄〃" />
- </div>
- </div>
- </Modal>
-</template>
diff --git a/src/views/materialstock/components/select.vue b/src/views/materialstock/components/select.vue
deleted file mode 100644
index ea05867..0000000
--- a/src/views/materialstock/components/select.vue
+++ /dev/null
@@ -1,158 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmMaterialStockApi } from '#/api/mes/wm/materialstock';
-
-import { computed, ref, useAttrs, watch } from 'vue';
-
-import { IconifyIcon } from '@vben/icons';
-
-import { Input, Tooltip } from 'ant-design-vue';
-
-import { getMaterialStock } from '#/api/mes/wm/materialstock';
-
-import WmMaterialStockSelectDialog from './select-dialog.vue';
-
-defineOptions({ name: 'WmMaterialStockSelect', inheritAttrs: false });
-
-const props = withDefaults(
- defineProps<{
- allowClear?: boolean;
- batchId?: number;
- disabled?: boolean;
- itemId?: number;
- modelValue?: number;
- placeholder?: string;
- virtualFilter?: 'all' | 'exclude' | 'only';
- warehouseId?: number;
- }>(),
- {
- allowClear: true,
- batchId: undefined,
- disabled: false,
- itemId: undefined,
- modelValue: undefined,
- placeholder: '璇烽�夋嫨搴撳瓨',
- virtualFilter: 'exclude',
- warehouseId: undefined,
- },
-);
-
-const emit = defineEmits<{
- change: [item: MesWmMaterialStockApi.MaterialStock | undefined];
- 'update:modelValue': [value: number | undefined];
-}>();
-
-const attrs = useAttrs();
-const dialogRef = ref<InstanceType<typeof WmMaterialStockSelectDialog>>();
-const hovering = ref(false);
-const selectedItem = ref<MesWmMaterialStockApi.MaterialStock>();
-
-const displayLabel = computed(() => {
- const item = selectedItem.value;
- if (!item) {
- return '';
- }
- return `${item.warehouseName || '-'} / ${item.batchCode || '-'} / 鏁伴噺:${item.quantity}`;
-});
-
-const showClear = computed(
- () =>
- props.allowClear &&
- !props.disabled &&
- hovering.value &&
- props.modelValue !== null,
-);
-
-/** 鏍规嵁 ID 鍗曟潯鏌ヨ搴撳瓨淇℃伅锛堢敤浜庣紪杈戝洖鏄撅級 */
-async function resolveItemById(id: number | undefined) {
- if (!id) {
- selectedItem.value = undefined;
- return;
- }
- if (selectedItem.value?.id === id) {
- return;
- }
- selectedItem.value = await getMaterialStock(id);
-}
-
-watch(() => props.modelValue, resolveItemById, { 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]
- ) as number[];
- dialogRef.value?.open(selectedIds, { multiple: false });
-}
-
-/** 寮圭獥閫変腑鍥炶皟 */
-function handleSelected(rows: MesWmMaterialStockApi.MaterialStock[]) {
- const item = rows[0];
- if (!item) {
- return;
- }
- selectedItem.value = item;
- emit('update:modelValue', item.id);
- emit('change', item);
-}
-</script>
-
-<template>
- <div
- v-bind="attrs"
- class="w-full"
- :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.itemName || '-' }}</div>
- <div>鎵规锛歿{ selectedItem.batchCode || '-' }}</div>
- <div>鏁伴噺锛歿{ selectedItem.quantity ?? '-' }}</div>
- <div>浠撳簱锛歿{ selectedItem.warehouseName || '-' }}</div>
- <div>搴撳尯锛歿{ selectedItem.locationName || '-' }}</div>
- <div>搴撲綅锛歿{ selectedItem.areaName || '-' }}</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>
- <WmMaterialStockSelectDialog
- ref="dialogRef"
- :batch-id="batchId"
- :item-id="itemId"
- :virtual-filter="virtualFilter"
- :warehouse-id="warehouseId"
- @selected="handleSelected"
- />
-</template>
diff --git a/src/views/materialstock/data.ts b/src/views/materialstock/data.ts
deleted file mode 100644
index c6f0ceb..0000000
--- a/src/views/materialstock/data.ts
+++ /dev/null
@@ -1,306 +0,0 @@
-import type { VbenFormSchema } from '#/adapter/form';
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmMaterialStockApi } from '#/api/mes/wm/materialstock';
-
-import { markRaw } from 'vue';
-
-import { useAccess } from '@vben/access';
-import { DICT_TYPE } from '@vben/constants';
-
-import { MdItemSelect } from '#/views/mes/md/item/components';
-import { MdVendorSelect } from '#/views/mes/md/vendor/components';
-
-import {
- WmWarehouseAreaSelect,
- WmWarehouseLocationSelect,
- WmWarehouseSelect,
-} from '../warehouse/components';
-
-/** 鍒楄〃鐨勬悳绱㈣〃鍗� */
-export function useGridFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'itemId',
- label: '鐗╂枡',
- component: markRaw(MdItemSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨鐗╂枡',
- },
- },
- {
- fieldName: 'batchCode',
- label: '鎵规鍙�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ユ壒娆″彿',
- },
- },
- {
- fieldName: 'warehouseId',
- label: '浠撳簱',
- component: markRaw(WmWarehouseSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨浠撳簱',
- },
- },
- {
- fieldName: 'locationId',
- label: '搴撳尯',
- component: markRaw(WmWarehouseLocationSelect),
- dependencies: {
- triggerFields: ['warehouseId'],
- componentProps: (values) => ({
- warehouseId: values.warehouseId,
- placeholder: '璇烽�夋嫨搴撳尯',
- }),
- // 浠撳簱鍒囨崲鏃舵竻绌哄簱鍖猴紝閬垮厤鏃у簱鍖烘潯浠舵畫鐣�
- trigger: (values, formApi) => {
- if (values.locationId !== undefined) {
- void formApi.setFieldValue('locationId', undefined);
- }
- },
- },
- },
- {
- fieldName: 'frozen',
- label: '鏄惁鍐荤粨',
- component: 'Select',
- componentProps: {
- allowClear: true,
- options: [
- { label: '鏄�', value: true },
- { label: '鍚�', value: false },
- ],
- placeholder: '璇烽�夋嫨',
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勫瓧娈� */
-export function useGridColumns(
- onFrozenChange: (
- newFrozen: boolean,
- row: MesWmMaterialStockApi.MaterialStock,
- ) => Promise<boolean | undefined>,
-): VxeTableGridOptions<MesWmMaterialStockApi.MaterialStock>['columns'] {
- const { hasAccessByCodes } = useAccess();
- return [
- {
- field: 'itemCode',
- title: '浜у搧鐗╂枡缂栫爜',
- minWidth: 120,
- },
- {
- field: 'itemName',
- title: '浜у搧鐗╂枡鍚嶇О',
- minWidth: 140,
- },
- {
- field: 'specification',
- title: '瑙勬牸鍨嬪彿',
- minWidth: 120,
- },
- {
- field: 'quantity',
- title: '鍦ㄥ簱鏁伴噺',
- width: 100,
- },
- {
- field: 'unitMeasureName',
- title: '鍗曚綅',
- width: 80,
- },
- {
- field: 'batchCode',
- title: '鎵规鍙�',
- minWidth: 140,
- slots: { default: 'batchCode' },
- },
- {
- field: 'warehouseName',
- title: '浠撳簱',
- minWidth: 100,
- },
- {
- field: 'locationName',
- title: '搴撳尯',
- minWidth: 100,
- },
- {
- field: 'areaName',
- title: '搴撲綅',
- minWidth: 100,
- slots: { default: 'areaName' },
- },
- {
- field: 'receiptTime',
- title: '鍏ュ簱鏃ユ湡',
- width: 180,
- formatter: 'formatDateTime',
- },
- {
- field: 'frozen',
- title: '鍐荤粨',
- width: 90,
- cellRender: {
- name: 'CellSwitch',
- attrs: { beforeChange: onFrozenChange },
- props: {
- checkedValue: true,
- // 鍐荤粨寮�鍏冲彈鏇存柊鏉冮檺鎺у埗锛屾棤鏉冮檺鏃剁鐢紝淇濇寔涓庢簮椤圭洰 v-hasPermi 涓�鑷�
- disabled: !hasAccessByCodes(['mes:wm-material-stock:update']),
- unCheckedValue: false,
- },
- },
- },
- ];
-}
-
-/** 閫夋嫨寮圭獥鐨勬悳绱㈣〃鍗� */
-export function useSelectGridFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'itemId',
- label: '鐗╂枡',
- component: markRaw(MdItemSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨鐗╂枡',
- },
- },
- {
- fieldName: 'vendorId',
- label: '渚涘簲鍟�',
- component: markRaw(MdVendorSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨渚涘簲鍟�',
- },
- },
- {
- fieldName: 'batchCode',
- label: '鎵规鍙�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ユ壒娆″彿',
- },
- },
- {
- fieldName: 'warehouseId',
- label: '浠撳簱',
- component: markRaw(WmWarehouseSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨浠撳簱',
- },
- },
- {
- fieldName: 'locationId',
- label: '搴撳尯',
- component: markRaw(WmWarehouseLocationSelect),
- dependencies: {
- triggerFields: ['warehouseId'],
- componentProps: (values) => ({
- warehouseId: values.warehouseId,
- placeholder: '璇烽�夋嫨搴撳尯',
- }),
- // 浠撳簱鍒囨崲鏃舵竻绌哄簱鍖�
- trigger: (values, formApi) => {
- if (values.locationId !== undefined) {
- void formApi.setFieldValue('locationId', undefined);
- }
- },
- },
- },
- {
- fieldName: 'areaId',
- label: '搴撲綅',
- component: markRaw(WmWarehouseAreaSelect),
- dependencies: {
- triggerFields: ['warehouseId', 'locationId'],
- componentProps: (values) => ({
- locationId: values.locationId,
- placeholder: '璇烽�夋嫨搴撲綅',
- }),
- // 浠撳簱鎴栧簱鍖哄垏鎹㈡椂娓呯┖搴撲綅
- trigger: (values, formApi) => {
- if (values.areaId !== undefined) {
- void formApi.setFieldValue('areaId', undefined);
- }
- },
- },
- },
- ];
-}
-
-/** 閫夋嫨寮圭獥鐨勫瓧娈� */
-export function useSelectGridColumns(
- multiple = false,
-): VxeTableGridOptions<MesWmMaterialStockApi.MaterialStock>['columns'] {
- return [
- {
- type: multiple ? 'checkbox' : 'radio',
- width: 50,
- },
- {
- field: 'itemCode',
- title: '浜у搧鐗╂枡缂栫爜',
- minWidth: 120,
- },
- {
- field: 'itemName',
- title: '浜у搧鐗╂枡鍚嶇О',
- minWidth: 140,
- },
- {
- field: 'specification',
- title: '瑙勬牸鍨嬪彿',
- minWidth: 120,
- },
- {
- field: 'unitMeasureName',
- title: '鍗曚綅',
- width: 80,
- },
- {
- field: 'batchCode',
- title: '鍏ュ簱鎵规鍙�',
- minWidth: 120,
- },
- {
- field: 'warehouseName',
- title: '浠撳簱',
- minWidth: 100,
- },
- {
- field: 'locationName',
- title: '搴撳尯',
- minWidth: 100,
- },
- {
- field: 'areaName',
- title: '搴撲綅',
- minWidth: 100,
- },
- {
- field: 'quantity',
- title: '鍦ㄥ簱鏁伴噺',
- width: 100,
- },
- {
- field: 'receiptTime',
- title: '鍏ュ簱鏃ユ湡',
- width: 180,
- formatter: 'formatDateTime',
- },
- {
- field: 'frozen',
- title: '鍐荤粨',
- width: 80,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.INFRA_BOOLEAN_STRING },
- },
- },
- ];
-}
diff --git a/src/views/materialstock/index.vue b/src/views/materialstock/index.vue
deleted file mode 100644
index a9353f0..0000000
--- a/src/views/materialstock/index.vue
+++ /dev/null
@@ -1,175 +0,0 @@
-<script lang="ts" setup>
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmMaterialStockApi } from '#/api/mes/wm/materialstock';
-
-import { ref } from 'vue';
-
-import { confirm, Page, useVbenModal } from '@vben/common-ui';
-import { downloadFileFromBlobPart } from '@vben/utils';
-
-import { Button, Card, message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import {
- exportMaterialStock,
- getMaterialStockPage,
- updateMaterialStockFrozen,
-} from '#/api/mes/wm/materialstock';
-import { $t } from '#/locales';
-import { MdItemTypeTree } from '#/views/mes/md/item/type/components';
-import { WmBatchDetail } from '#/views/wls/batch/components';
-import AreaForm from '#/views/wls/warehouse/area/modules/form.vue';
-
-import { useGridColumns, useGridFormSchema } from './data';
-
-const [AreaModal, areaModalApi] = useVbenModal({
- connectedComponent: AreaForm,
- destroyOnClose: true,
-});
-
-const batchDetailRef = ref<InstanceType<typeof WmBatchDetail>>();
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- gridApi.query();
-}
-
-/** 瀵煎嚭琛ㄦ牸 */
-async function handleExport() {
- const data = await exportMaterialStock({
- ...(await gridApi.formApi.getValues()),
- itemTypeId: searchItemTypeId.value,
- });
- downloadFileFromBlobPart({ fileName: '搴撳瓨鍙拌处.xls', source: data });
-}
-
-/** 閫夋嫨鐗╂枡鍒嗙被 */
-const searchItemTypeId = ref<number | undefined>(undefined);
-function handleTypeNodeClick(row: undefined | { id?: number }) {
- searchItemTypeId.value = row?.id;
- handleRefresh();
-}
-
-/** 鎵撳紑搴撲綅璇︽儏寮圭獥 */
-function handleOpenAreaDetail(row: MesWmMaterialStockApi.MaterialStock) {
- if (!row.areaId) {
- return;
- }
- areaModalApi.setData({ formType: 'detail', id: row.areaId }).open();
-}
-
-/** 鎵撳紑鎵规璇︽儏寮圭獥 */
-function handleOpenBatchDetail(row: MesWmMaterialStockApi.MaterialStock) {
- if (!row.batchId) {
- return;
- }
- batchDetailRef.value?.open(row.batchId);
-}
-
-/** 澶勭悊鍐荤粨鐘舵�佸垏鎹� */
-async function handleFrozenChange(
- newFrozen: boolean,
- row: MesWmMaterialStockApi.MaterialStock,
-): Promise<boolean | undefined> {
- const text = newFrozen ? '鍐荤粨' : '瑙e喕';
- try {
- await confirm(`纭瑕�"${text}"璇ュ簱瀛樿褰曞悧锛焋);
- } catch {
- return false;
- }
- // 鏇存柊鍐荤粨鐘舵��
- await updateMaterialStockFrozen({
- id: row.id!,
- frozen: newFrozen,
- });
- // 鎻愮ず骞惰繑鍥炴垚鍔�
- message.success(`${text}鎴愬姛`);
- return true;
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- formOptions: {
- schema: useGridFormSchema(),
- },
- gridOptions: {
- columns: useGridColumns(handleFrozenChange),
- height: 'auto',
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }, formValues) => {
- return await getMaterialStockPage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- ...formValues,
- itemTypeId: searchItemTypeId.value,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- search: true,
- },
- } as VxeTableGridOptions<MesWmMaterialStockApi.MaterialStock>,
-});
-</script>
-
-<template>
- <Page auto-content-height><AreaModal />
- <WmBatchDetail ref="batchDetailRef" />
-
- <div class="flex h-full w-full">
- <!-- 宸︿晶鐗╂枡鍒嗙被鏍� -->
- <Card class="mr-4 h-full w-1/6">
- <MdItemTypeTree @node-click="handleTypeNodeClick" />
- </Card>
- <!-- 鍙充晶搴撳瓨鍙拌处鍒楄〃 -->
- <div class="w-5/6">
- <Grid table-title="搴撳瓨鍙拌处鍒楄〃">
- <template #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: $t('ui.actionTitle.export'),
- type: 'primary',
- icon: ACTION_ICON.DOWNLOAD,
- auth: ['mes:wm-material-stock:export'],
- onClick: handleExport,
- },
- ]"
- />
- </template>
- <template #batchCode="{ row }">
- <Button
- v-if="row.batchId"
- :title="row.batchCode"
- size="small"
- type="link"
- @click="handleOpenBatchDetail(row)"
- >
- {{ row.batchCode }}
- </Button>
- <span v-else>-</span>
- </template>
- <template #areaName="{ row }">
- <Button
- v-if="row.areaId"
- :title="row.areaName"
- size="small"
- type="link"
- @click="handleOpenAreaDetail(row)"
- >
- {{ row.areaName }}
- </Button>
- <span v-else>-</span>
- </template>
- </Grid>
- </div>
- </div>
- </Page>
-</template>
diff --git a/src/views/miscissue/data.ts b/src/views/miscissue/data.ts
deleted file mode 100644
index a61e01b..0000000
--- a/src/views/miscissue/data.ts
+++ /dev/null
@@ -1,452 +0,0 @@
-import type { VbenFormApi, VbenFormSchema } from '#/adapter/form';
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmMaterialStockApi } from '#/api/mes/wm/materialstock';
-import type { MesWmMiscIssueApi } from '#/api/mes/wm/miscissue';
-import type { MesWmMiscIssueLineApi } from '#/api/mes/wm/miscissue/line';
-
-import { h, markRaw } from 'vue';
-
-import { DICT_TYPE, MesAutoCodeRuleCode } from '@vben/constants';
-import { getDictOptions } from '@vben/hooks';
-
-import { Button } from 'ant-design-vue';
-
-import { generateAutoCode } from '#/api/mes/md/autocode/record';
-import { getRangePickerDefaultProps } from '#/utils';
-import { WmMaterialStockSelect } from '#/views/wls/materialstock/components';
-import {
- WmWarehouseAreaSelect,
- WmWarehouseLocationSelect,
- WmWarehouseSelect,
-} from '#/views/wls/warehouse/components';
-
-/** 琛ㄥ崟绫诲瀷 */
-export type FormType = 'create' | 'detail' | 'finish' | 'update';
-
-/** 琛ㄥ崟澶撮儴鏄惁鍙锛堣鎯呫�佹墽琛屽嚭搴撴�侊級 */
-function isHeaderReadonly(formType: FormType): boolean {
- return formType === 'detail' || formType === 'finish';
-}
-
-/** 鏂板/淇敼鐨勮〃鍗� */
-export function useFormSchema(
- formType: FormType,
- formApi?: VbenFormApi,
-): VbenFormSchema[] {
- return [
- {
- fieldName: 'id',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'status',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'code',
- label: '鍑哄簱鍗曠紪鍙�',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ュ嚭搴撳崟缂栧彿',
- },
- rules: 'required',
- suffix: isHeaderReadonly(formType)
- ? undefined
- : () =>
- h(
- Button,
- {
- type: 'default',
- onClick: async () => {
- const code = await generateAutoCode(
- MesAutoCodeRuleCode.WM_MISC_ISSUE_CODE,
- );
- await formApi?.setFieldValue('code', code);
- },
- },
- { default: () => '鐢熸垚' },
- ),
- },
- {
- fieldName: 'name',
- label: '鍑哄簱鍗曞悕绉�',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ュ嚭搴撳崟鍚嶇О',
- },
- rules: 'required',
- },
- {
- fieldName: 'type',
- label: '涓氬姟绫诲瀷',
- component: 'Select',
- componentProps: {
- options: getDictOptions(DICT_TYPE.MES_WM_MISC_ISSUE_TYPE, 'number'),
- placeholder: '璇烽�夋嫨涓氬姟绫诲瀷',
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'issueDate',
- label: '鍑哄簱鏃ユ湡',
- component: 'DatePicker',
- componentProps: {
- format: 'YYYY-MM-DD',
- placeholder: '璇烽�夋嫨鍑哄簱鏃ユ湡',
- valueFormat: 'x',
- },
- rules: 'required',
- },
- {
- fieldName: 'sourceDocType',
- label: '鏉ユ簮鍗曟嵁绫诲瀷',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ユ潵婧愬崟鎹被鍨�',
- },
- },
- {
- fieldName: 'sourceDocCode',
- label: '鏉ユ簮鍗曟嵁缂栧彿',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ユ潵婧愬崟鎹紪鍙�',
- },
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勬悳绱㈣〃鍗� */
-export function useGridFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'code',
- label: '鍑哄簱鍗曠紪鍙�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ュ嚭搴撳崟缂栧彿',
- },
- },
- {
- fieldName: 'name',
- label: '鍑哄簱鍗曞悕绉�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ュ嚭搴撳崟鍚嶇О',
- },
- },
- {
- fieldName: 'type',
- label: '涓氬姟绫诲瀷',
- component: 'Select',
- componentProps: {
- allowClear: true,
- options: getDictOptions(DICT_TYPE.MES_WM_MISC_ISSUE_TYPE, 'number'),
- placeholder: '璇烽�夋嫨涓氬姟绫诲瀷',
- },
- },
- {
- fieldName: 'sourceDocType',
- label: '鏉ユ簮鍗曟嵁绫诲瀷',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ユ潵婧愬崟鎹被鍨�',
- },
- },
- {
- fieldName: 'sourceDocCode',
- label: '鏉ユ簮鍗曟嵁缂栧彿',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ユ潵婧愬崟鎹紪鍙�',
- },
- },
- {
- fieldName: 'issueDate',
- label: '鍑哄簱鏃ユ湡',
- component: 'RangePicker',
- componentProps: {
- ...getRangePickerDefaultProps(),
- allowClear: true,
- },
- },
- {
- fieldName: 'status',
- label: '鍗曟嵁鐘舵��',
- component: 'Select',
- componentProps: {
- allowClear: true,
- options: getDictOptions(DICT_TYPE.MES_WM_MISC_ISSUE_STATUS, 'number'),
- placeholder: '璇烽�夋嫨鍗曟嵁鐘舵��',
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勫瓧娈� */
-export function useGridColumns(): VxeTableGridOptions<MesWmMiscIssueApi.MiscIssue>['columns'] {
- return [
- {
- field: 'code',
- title: '鍑哄簱鍗曠紪鍙�',
- minWidth: 160,
- slots: { default: 'code' },
- },
- {
- field: 'name',
- title: '鍑哄簱鍗曞悕绉�',
- minWidth: 150,
- },
- {
- field: 'type',
- title: '涓氬姟绫诲瀷',
- minWidth: 120,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_MISC_ISSUE_TYPE },
- },
- },
- {
- field: 'sourceDocType',
- title: '鏉ユ簮鍗曟嵁绫诲瀷',
- minWidth: 120,
- },
- {
- field: 'sourceDocCode',
- title: '鏉ユ簮鍗曟嵁缂栧彿',
- minWidth: 150,
- },
- {
- field: 'issueDate',
- title: '鍑哄簱鏃ユ湡',
- width: 180,
- formatter: 'formatDate',
- },
- {
- field: 'status',
- title: '鍗曟嵁鐘舵��',
- minWidth: 100,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_MISC_ISSUE_STATUS },
- },
- },
- {
- title: '鎿嶄綔',
- width: 240,
- fixed: 'right',
- slots: { default: 'actions' },
- },
- ];
-}
-
-/** 鍑哄簱鍗曡瀛愯〃鐨勫瓧娈� */
-export function useLineGridColumns(
- editable = true,
-): VxeTableGridOptions<MesWmMiscIssueLineApi.MiscIssueLine>['columns'] {
- return [
- {
- field: 'itemCode',
- title: '鐗╂枡缂栫爜',
- minWidth: 120,
- },
- {
- field: 'itemName',
- title: '鐗╂枡鍚嶇О',
- minWidth: 140,
- },
- {
- field: 'specification',
- title: '瑙勬牸鍨嬪彿',
- minWidth: 120,
- },
- {
- field: 'unitMeasureName',
- title: '鍗曚綅',
- width: 80,
- },
- {
- field: 'quantity',
- title: '鍑哄簱鏁伴噺',
- width: 100,
- },
- {
- field: 'batchCode',
- title: '鎵规缂栫爜',
- minWidth: 120,
- },
- {
- field: 'warehouseName',
- title: '浠撳簱',
- minWidth: 120,
- },
- {
- field: 'locationName',
- title: '搴撳尯',
- minWidth: 120,
- },
- {
- field: 'areaName',
- title: '搴撲綅',
- minWidth: 120,
- },
- ...(editable
- ? [
- {
- title: '鎿嶄綔',
- width: 120,
- fixed: 'right',
- slots: { default: 'actions' },
- } as const,
- ]
- : []),
- ];
-}
-
-/** 鍑哄簱鍗曡鏂板/淇敼鐨勮〃鍗� */
-export function useLineFormSchema(formApi?: VbenFormApi): VbenFormSchema[] {
- return [
- {
- fieldName: 'itemId',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'quantityMax',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'materialStockId',
- label: '搴撳瓨鐗╄祫',
- component: markRaw(WmMaterialStockSelect),
- componentProps: {
- // 閫夋嫨搴撳瓨鐗╄祫鍚庯紝鑷姩鍥炲~鐗╂枡銆佹壒娆″彿銆佷粨搴撲綅缃拰鏈�澶у彲鍑哄簱鏁伴噺
- onChange: async (stock?: MesWmMaterialStockApi.MaterialStock) => {
- await formApi?.setValues({
- areaId: stock?.areaId,
- batchCode: stock?.batchCode,
- itemId: stock?.itemId,
- locationId: stock?.locationId,
- quantityMax: stock?.quantity,
- warehouseId: stock?.warehouseId,
- });
- },
- },
- rules: 'selectRequired',
- dependencies: {
- triggerFields: ['itemId'],
- componentProps: (values) => ({
- itemId: values.itemId,
- }),
- },
- },
- {
- fieldName: 'quantity',
- label: '鍑哄簱鏁伴噺',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0.01,
- placeholder: '璇疯緭鍏ュ嚭搴撴暟閲�',
- precision: 2,
- },
- rules: 'required',
- dependencies: {
- triggerFields: ['quantityMax'],
- componentProps: (values) => ({
- class: '!w-full',
- max: values.quantityMax,
- min: 0.01,
- placeholder: '璇疯緭鍏ュ嚭搴撴暟閲�',
- precision: 2,
- }),
- },
- },
- {
- fieldName: 'batchCode',
- label: '鎵规鍙�',
- component: 'Input',
- componentProps: {
- disabled: true,
- placeholder: '鎵规鍙�',
- },
- },
- {
- fieldName: 'warehouseId',
- label: '浠撳簱',
- component: markRaw(WmWarehouseSelect),
- componentProps: {
- disabled: true,
- },
- },
- {
- fieldName: 'locationId',
- label: '搴撳尯',
- component: markRaw(WmWarehouseLocationSelect),
- componentProps: {
- disabled: true,
- },
- dependencies: {
- triggerFields: ['warehouseId'],
- componentProps: (values) => ({
- disabled: true,
- warehouseId: values.warehouseId,
- }),
- },
- },
- {
- fieldName: 'areaId',
- label: '搴撲綅',
- component: markRaw(WmWarehouseAreaSelect),
- componentProps: {
- disabled: true,
- },
- dependencies: {
- triggerFields: ['locationId'],
- componentProps: (values) => ({
- disabled: true,
- locationId: values.locationId,
- }),
- },
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
diff --git a/src/views/miscissue/index.vue b/src/views/miscissue/index.vue
deleted file mode 100644
index 90406ca..0000000
--- a/src/views/miscissue/index.vue
+++ /dev/null
@@ -1,187 +0,0 @@
-<script lang="ts" setup>
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmMiscIssueApi } from '#/api/mes/wm/miscissue';
-
-import { Page, useVbenModal } from '@vben/common-ui';
-import { MesWmMiscIssueStatusEnum } from '@vben/constants';
-import { downloadFileFromBlobPart } from '@vben/utils';
-
-import { Button, message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import {
- cancelMiscIssue,
- deleteMiscIssue,
- exportMiscIssue,
- getMiscIssuePage,
-} from '#/api/mes/wm/miscissue';
-import { $t } from '#/locales';
-
-import { useGridColumns, useGridFormSchema } from './data';
-import Form from './modules/form.vue';
-
-const [FormModal, formModalApi] = useVbenModal({
- connectedComponent: Form,
- destroyOnClose: true,
-});
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- gridApi.query();
-}
-
-/** 鍒涘缓鏉傞」鍑哄簱鍗� */
-function handleCreate() {
- formModalApi.setData({ formType: 'create' }).open();
-}
-
-/** 鏌ョ湅鏉傞」鍑哄簱鍗� */
-function handleDetail(row: MesWmMiscIssueApi.MiscIssue) {
- formModalApi.setData({ formType: 'detail', id: row.id }).open();
-}
-
-/** 缂栬緫鏉傞」鍑哄簱鍗� */
-function handleEdit(row: MesWmMiscIssueApi.MiscIssue) {
- formModalApi.setData({ formType: 'update', id: row.id }).open();
-}
-
-/** 鎵ц鍑哄簱 */
-function handleFinish(row: MesWmMiscIssueApi.MiscIssue) {
- formModalApi.setData({ formType: 'finish', id: row.id }).open();
-}
-
-/** 鍒犻櫎鏉傞」鍑哄簱鍗� */
-async function handleDelete(row: MesWmMiscIssueApi.MiscIssue) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.code]),
- duration: 0,
- });
- try {
- await deleteMiscIssue(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.code]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-/** 鍙栨秷鏉傞」鍑哄簱鍗� */
-async function handleCancel(row: MesWmMiscIssueApi.MiscIssue) {
- await cancelMiscIssue(row.id!);
- message.success('鍙栨秷鎴愬姛');
- handleRefresh();
-}
-
-/** 瀵煎嚭琛ㄦ牸 */
-async function handleExport() {
- const data = await exportMiscIssue(await gridApi.formApi.getValues());
- downloadFileFromBlobPart({ fileName: '鏉傞」鍑哄簱鍗�.xls', source: data });
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- formOptions: {
- schema: useGridFormSchema(),
- },
- gridOptions: {
- columns: useGridColumns(),
- height: 'auto',
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }, formValues) => {
- return await getMiscIssuePage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- ...formValues,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- search: true,
- },
- } as VxeTableGridOptions<MesWmMiscIssueApi.MiscIssue>,
-});
-</script>
-
-<template>
- <Page auto-content-height><FormModal @success="handleRefresh" />
-
- <Grid table-title="鏉傞」鍑哄簱鍗曞垪琛�">
- <template #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: $t('ui.actionTitle.create', ['鏉傞」鍑哄簱鍗�']),
- type: 'primary',
- icon: ACTION_ICON.ADD,
- auth: ['mes:wm-misc-issue:create'],
- onClick: handleCreate,
- },
- {
- label: $t('ui.actionTitle.export'),
- type: 'primary',
- icon: ACTION_ICON.DOWNLOAD,
- auth: ['mes:wm-misc-issue:export'],
- onClick: handleExport,
- },
- ]"
- />
- </template>
- <template #code="{ row }">
- <Button type="link" @click="handleDetail(row)">
- {{ row.code }}
- </Button>
- </template>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- auth: ['mes:wm-misc-issue:update'],
- ifShow: row.status === MesWmMiscIssueStatusEnum.PREPARE,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- auth: ['mes:wm-misc-issue:delete'],
- ifShow: row.status === MesWmMiscIssueStatusEnum.PREPARE,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.code]),
- confirm: handleDelete.bind(null, row),
- },
- },
- {
- label: '鎵ц鍑哄簱',
- type: 'link',
- auth: ['mes:wm-misc-issue:finish'],
- ifShow: row.status === MesWmMiscIssueStatusEnum.APPROVED,
- onClick: handleFinish.bind(null, row),
- },
- {
- label: '鍙栨秷',
- type: 'link',
- danger: true,
- auth: ['mes:wm-misc-issue:update'],
- ifShow: row.status === MesWmMiscIssueStatusEnum.APPROVED,
- popConfirm: {
- title: '纭鍙栨秷璇ユ潅椤瑰嚭搴撳崟锛熷彇娑堝悗涓嶅彲鎭㈠銆�',
- confirm: handleCancel.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </Page>
-</template>
diff --git a/src/views/miscissue/modules/form.vue b/src/views/miscissue/modules/form.vue
deleted file mode 100644
index 3883b97..0000000
--- a/src/views/miscissue/modules/form.vue
+++ /dev/null
@@ -1,199 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { MesWmMiscIssueApi } from '#/api/mes/wm/miscissue';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-import { MesWmMiscIssueStatusEnum } from '@vben/constants';
-
-import { Button, Divider, message, Popconfirm } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createMiscIssue,
- finishMiscIssue,
- getMiscIssue,
- submitMiscIssue,
- updateMiscIssue,
-} from '#/api/mes/wm/miscissue';
-import { $t } from '#/locales';
-
-import { useFormSchema } from '../data';
-import LineList from './line-list.vue';
-
-const emit = defineEmits(['success']);
-const formType = ref<FormType>('create');
-const formData = ref<MesWmMiscIssueApi.MiscIssue>();
-const originalSnapshot = ref(''); // 琛ㄥ崟鍘熷鏁版嵁蹇収锛岀敤浜庢彁浜ゆ椂璺宠繃鏈彉鏇寸殑淇濆瓨璇锋眰
-const isEditable = computed(() =>
- // 鏄惁涓虹紪杈戞ā寮忥紙鍙繚瀛橈級
- ['create', 'update'].includes(formType.value),
-);
-const isFinish = computed(() => formType.value === 'finish'); // 鏄惁涓烘墽琛屽嚭搴撴ā寮�
-const canSubmit = computed(
- () =>
- // 鏄惁鍙彁浜�
- formType.value === 'update' &&
- formData.value?.status === MesWmMiscIssueStatusEnum.PREPARE,
-);
-const getTitle = computed(() => {
- if (formType.value === 'detail') {
- return $t('ui.actionTitle.view', ['鏉傞」鍑哄簱鍗�']);
- }
- if (formType.value === 'finish') {
- return '鎵ц鍑哄簱';
- }
- return formType.value === 'update'
- ? $t('ui.actionTitle.edit', ['鏉傞」鍑哄簱鍗�'])
- : $t('ui.actionTitle.create', ['鏉傞」鍑哄簱鍗�']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 110,
- },
- layout: 'horizontal',
- schema: [],
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-/** 鎻愪氦鍑哄簱鍗曪細琛ㄥ崟鏈変慨鏀规椂鍏堜繚瀛橈紝鍐嶈皟鐢ㄦ彁浜ゆ帴鍙� */
-async function handleSubmit() {
- const { valid } = await formApi.validate();
- if (!valid || !formData.value?.id) {
- return;
- }
- modalApi.lock();
- try {
- const current = JSON.stringify(await formApi.getValues());
- if (current !== originalSnapshot.value) {
- const data = (await formApi.getValues()) as MesWmMiscIssueApi.MiscIssue;
- await updateMiscIssue({ ...formData.value, ...data });
- originalSnapshot.value = current;
- }
- await submitMiscIssue(formData.value.id);
- message.success('鎻愪氦鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-/** 鎵ц鍑哄簱 */
-async function handleFinish() {
- if (!formData.value?.id) {
- return;
- }
- modalApi.lock();
- try {
- await finishMiscIssue(formData.value.id);
- message.success('鍑哄簱鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- if (!isEditable.value) {
- await modalApi.close();
- return;
- }
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data = (await formApi.getValues()) as MesWmMiscIssueApi.MiscIssue;
- try {
- if (formData.value?.id) {
- await updateMiscIssue({ ...formData.value, ...data });
- formData.value = { ...formData.value, ...data };
- } else {
- const id = await createMiscIssue(data);
- formData.value = {
- ...data,
- id,
- status: MesWmMiscIssueStatusEnum.PREPARE,
- };
- await formApi.setFieldValue('id', id);
- await formApi.setFieldValue('status', formData.value.status);
- formType.value = 'update';
- }
- originalSnapshot.value = JSON.stringify(await formApi.getValues());
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- originalSnapshot.value = '';
- return;
- }
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{ formType: FormType; id?: number }>();
- formType.value = data.formType;
- formApi.setState({ schema: useFormSchema(formType.value, formApi) });
- formApi.setDisabled(
- formType.value === 'detail' || formType.value === 'finish',
- );
- modalApi.setState({ showConfirmButton: isEditable.value });
- if (data?.id) {
- modalApi.lock();
- try {
- formData.value = await getMiscIssue(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- }
- originalSnapshot.value = JSON.stringify(await formApi.getValues());
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- <!-- 闈炴柊寤烘ā寮忓睍绀虹墿鏂欎俊鎭� -->
- <template v-if="formData?.id">
- <Divider>鐗╂枡淇℃伅</Divider>
- <div class="mx-4">
- <LineList :form-type="formType" :issue-id="formData.id" />
- </div>
- </template>
- <template #prepend-footer>
- <div class="flex flex-auto items-center gap-2">
- <Popconfirm
- v-if="canSubmit"
- title="纭鎻愪氦璇ユ潅椤瑰嚭搴撳崟锛熴�愭彁浜ゅ悗灏嗕笉鑳戒慨鏀广��"
- @confirm="handleSubmit"
- >
- <Button type="primary">鎻愪氦</Button>
- </Popconfirm>
- <Popconfirm
- v-if="isFinish"
- title="纭鎵ц鍑哄簱锛熸墽琛屽悗灏嗘洿鏂板簱瀛樺彴璐︺��"
- @confirm="handleFinish"
- >
- <Button type="primary">鎵ц鍑哄簱</Button>
- </Popconfirm>
- </div>
- </template>
- </Modal>
-</template>
diff --git a/src/views/miscissue/modules/line-form.vue b/src/views/miscissue/modules/line-form.vue
deleted file mode 100644
index bd689a6..0000000
--- a/src/views/miscissue/modules/line-form.vue
+++ /dev/null
@@ -1,98 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmMiscIssueLineApi } from '#/api/mes/wm/miscissue/line';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createMiscIssueLine,
- getMiscIssueLine,
- updateMiscIssueLine,
-} from '#/api/mes/wm/miscissue/line';
-import { $t } from '#/locales';
-
-import { useLineFormSchema } from '../data';
-
-const emit = defineEmits(['success']);
-const formData = ref<MesWmMiscIssueLineApi.MiscIssueLine>();
-const issueId = ref<number>(); // 鎵�灞炲嚭搴撳崟缂栧彿
-
-const getTitle = computed(() => {
- return formData.value?.id
- ? $t('ui.actionTitle.edit', ['鐗╂枡鍑哄簱鍗曡'])
- : $t('ui.actionTitle.create', ['鐗╂枡鍑哄簱鍗曡']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 90,
- },
- layout: 'horizontal',
- schema: useLineFormSchema(),
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data =
- (await formApi.getValues()) as MesWmMiscIssueLineApi.MiscIssueLine;
- data.issueId = issueId.value;
- try {
- await (formData.value?.id
- ? updateMiscIssueLine({ ...data, id: formData.value.id })
- : createMiscIssueLine(data));
- // 鍏抽棴骞舵彁绀�
- await modalApi.close();
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- return;
- }
- formApi.setState({ schema: useLineFormSchema(formApi) });
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{
- id?: number;
- issueId: number;
- }>();
- issueId.value = data.issueId;
- if (!data.id) {
- return;
- }
- modalApi.lock();
- try {
- formData.value = await getMiscIssueLine(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- </Modal>
-</template>
diff --git a/src/views/miscissue/modules/line-list.vue b/src/views/miscissue/modules/line-list.vue
deleted file mode 100644
index 8f8e9be..0000000
--- a/src/views/miscissue/modules/line-list.vue
+++ /dev/null
@@ -1,140 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmMiscIssueLineApi } from '#/api/mes/wm/miscissue/line';
-
-import { computed } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import {
- deleteMiscIssueLine,
- getMiscIssueLinePage,
-} from '#/api/mes/wm/miscissue/line';
-import { $t } from '#/locales';
-
-import { useLineGridColumns } from '../data';
-import LineForm from './line-form.vue';
-
-const props = defineProps<{
- formType: FormType;
- issueId: number;
-}>();
-
-const isEditable = computed(() =>
- // 鏄惁鍙紪杈戞槑缁嗚
- ['create', 'update'].includes(props.formType),
-);
-
-const [LineFormModal, lineFormModalApi] = useVbenModal({
- connectedComponent: LineForm,
- destroyOnClose: true,
-});
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- gridApi.query();
-}
-
-/** 娣诲姞鐗╂枡 */
-function handleCreate() {
- lineFormModalApi.setData({ issueId: props.issueId }).open();
-}
-
-/** 缂栬緫鐗╂枡 */
-function handleEdit(row: MesWmMiscIssueLineApi.MiscIssueLine) {
- lineFormModalApi.setData({ id: row.id, issueId: props.issueId }).open();
-}
-
-/** 鍒犻櫎鐗╂枡 */
-async function handleDelete(row: MesWmMiscIssueLineApi.MiscIssueLine) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.itemName]),
- duration: 0,
- });
- try {
- await deleteMiscIssueLine(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.itemName]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- gridOptions: {
- columns: useLineGridColumns(isEditable.value),
- height: 360,
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }) => {
- if (!props.issueId) {
- return { list: [], total: 0 };
- }
- return await getMiscIssueLinePage({
- issueId: props.issueId,
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- },
- } as VxeTableGridOptions<MesWmMiscIssueLineApi.MiscIssueLine>,
-});
-</script>
-
-<template>
- <div>
- <LineFormModal @success="handleRefresh" />
- <Grid table-title="鐗╂枡淇℃伅">
- <template v-if="isEditable" #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: '娣诲姞鐗╂枡',
- type: 'primary',
- icon: ACTION_ICON.ADD,
- onClick: handleCreate,
- },
- ]"
- />
- </template>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- ifShow: isEditable,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- ifShow: isEditable,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.itemName]),
- confirm: handleDelete.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </div>
-</template>
diff --git a/src/views/miscreceipt/data.ts b/src/views/miscreceipt/data.ts
deleted file mode 100644
index 25bc48e..0000000
--- a/src/views/miscreceipt/data.ts
+++ /dev/null
@@ -1,422 +0,0 @@
-import type { VbenFormApi, VbenFormSchema } from '#/adapter/form';
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmMiscReceiptApi } from '#/api/mes/wm/miscreceipt';
-import type { MesWmMiscReceiptLineApi } from '#/api/mes/wm/miscreceipt/line';
-
-import { h, markRaw } from 'vue';
-
-import { DICT_TYPE, MesAutoCodeRuleCode } from '@vben/constants';
-import { getDictOptions } from '@vben/hooks';
-
-import { Button } from 'ant-design-vue';
-
-import { generateAutoCode } from '#/api/mes/md/autocode/record';
-import { getRangePickerDefaultProps } from '#/utils';
-import { MdItemSelect } from '#/views/mes/md/item/components';
-import {
- WmWarehouseAreaSelect,
- WmWarehouseLocationSelect,
- WmWarehouseSelect,
-} from '#/views/wls/warehouse/components';
-
-/** 琛ㄥ崟绫诲瀷 */
-export type FormType = 'create' | 'detail' | 'finish' | 'update';
-
-/** 琛ㄥ崟澶撮儴鏄惁鍙锛堣鎯呫�佹墽琛屽叆搴撴�侊級 */
-function isHeaderReadonly(formType: FormType): boolean {
- return formType === 'detail' || formType === 'finish';
-}
-
-/** 鏂板/淇敼鐨勮〃鍗� */
-export function useFormSchema(
- formType: FormType,
- formApi?: VbenFormApi,
-): VbenFormSchema[] {
- return [
- {
- fieldName: 'id',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'status',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'code',
- label: '鍏ュ簱鍗曠紪鍙�',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ュ叆搴撳崟缂栧彿',
- },
- rules: 'required',
- suffix: isHeaderReadonly(formType)
- ? undefined
- : () =>
- h(
- Button,
- {
- type: 'default',
- onClick: async () => {
- const code = await generateAutoCode(
- MesAutoCodeRuleCode.WM_MISC_RECEIPT_CODE,
- );
- await formApi?.setFieldValue('code', code);
- },
- },
- { default: () => '鐢熸垚' },
- ),
- },
- {
- fieldName: 'name',
- label: '鍏ュ簱鍗曞悕绉�',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ュ叆搴撳崟鍚嶇О',
- },
- rules: 'required',
- },
- {
- fieldName: 'type',
- label: '鏉傞」绫诲瀷',
- component: 'Select',
- componentProps: {
- options: getDictOptions(DICT_TYPE.MES_WM_MISC_RECEIPT_TYPE, 'number'),
- placeholder: '璇烽�夋嫨鏉傞」绫诲瀷',
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'sourceDocType',
- label: '鏉ユ簮鍗曟嵁绫诲瀷',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ユ潵婧愬崟鎹被鍨�',
- },
- },
- {
- fieldName: 'sourceDocCode',
- label: '鏉ユ簮鍗曟嵁缂栫爜',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ユ潵婧愬崟鎹紪鐮�',
- },
- },
- {
- fieldName: 'receiptDate',
- label: '鍏ュ簱鏃ユ湡',
- component: 'DatePicker',
- componentProps: {
- format: 'YYYY-MM-DD',
- placeholder: '璇烽�夋嫨鍏ュ簱鏃ユ湡',
- valueFormat: 'x',
- },
- rules: 'required',
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勬悳绱㈣〃鍗� */
-export function useGridFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'code',
- label: '鍏ュ簱鍗曠紪鍙�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ュ叆搴撳崟缂栧彿',
- },
- },
- {
- fieldName: 'name',
- label: '鍏ュ簱鍗曞悕绉�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ュ叆搴撳崟鍚嶇О',
- },
- },
- {
- fieldName: 'type',
- label: '鏉傞」绫诲瀷',
- component: 'Select',
- componentProps: {
- allowClear: true,
- options: getDictOptions(DICT_TYPE.MES_WM_MISC_RECEIPT_TYPE, 'number'),
- placeholder: '璇烽�夋嫨鏉傞」绫诲瀷',
- },
- },
- {
- fieldName: 'sourceDocType',
- label: '鏉ユ簮鍗曟嵁绫诲瀷',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ユ潵婧愬崟鎹被鍨�',
- },
- },
- {
- fieldName: 'sourceDocCode',
- label: '鏉ユ簮鍗曟嵁缂栧彿',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ユ潵婧愬崟鎹紪鍙�',
- },
- },
- {
- fieldName: 'receiptDate',
- label: '鍏ュ簱鏃ユ湡',
- component: 'RangePicker',
- componentProps: {
- ...getRangePickerDefaultProps(),
- allowClear: true,
- },
- },
- {
- fieldName: 'status',
- label: '鍗曟嵁鐘舵��',
- component: 'Select',
- componentProps: {
- allowClear: true,
- options: getDictOptions(DICT_TYPE.MES_WM_MISC_RECEIPT_STATUS, 'number'),
- placeholder: '璇烽�夋嫨鍗曟嵁鐘舵��',
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勫瓧娈� */
-export function useGridColumns(): VxeTableGridOptions<MesWmMiscReceiptApi.MiscReceipt>['columns'] {
- return [
- {
- field: 'code',
- title: '鍏ュ簱鍗曠紪鍙�',
- minWidth: 160,
- slots: { default: 'code' },
- },
- {
- field: 'name',
- title: '鍏ュ簱鍗曞悕绉�',
- minWidth: 150,
- },
- {
- field: 'type',
- title: '鏉傞」绫诲瀷',
- minWidth: 100,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_MISC_RECEIPT_TYPE },
- },
- },
- {
- field: 'sourceDocType',
- title: '鏉ユ簮鍗曟嵁绫诲瀷',
- minWidth: 120,
- },
- {
- field: 'sourceDocCode',
- title: '鏉ユ簮鍗曟嵁缂栧彿',
- minWidth: 150,
- },
- {
- field: 'receiptDate',
- title: '鍏ュ簱鏃ユ湡',
- width: 180,
- formatter: 'formatDate',
- },
- {
- field: 'status',
- title: '鍗曟嵁鐘舵��',
- minWidth: 100,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_MISC_RECEIPT_STATUS },
- },
- },
- {
- title: '鎿嶄綔',
- width: 240,
- fixed: 'right',
- slots: { default: 'actions' },
- },
- ];
-}
-
-/** 鍏ュ簱鍗曡瀛愯〃鐨勫瓧娈� */
-export function useLineGridColumns(
- editable = true,
-): VxeTableGridOptions<MesWmMiscReceiptLineApi.MiscReceiptLine>['columns'] {
- return [
- {
- field: 'itemCode',
- title: '鐗╂枡缂栫爜',
- minWidth: 120,
- },
- {
- field: 'itemName',
- title: '鐗╂枡鍚嶇О',
- minWidth: 140,
- },
- {
- field: 'specification',
- title: '瑙勬牸鍨嬪彿',
- minWidth: 120,
- },
- {
- field: 'unitMeasureName',
- title: '鍗曚綅',
- width: 80,
- },
- {
- field: 'quantity',
- title: '鍏ュ簱鏁伴噺',
- width: 100,
- },
- {
- field: 'batchCode',
- title: '鎵规鍙�',
- minWidth: 120,
- },
- {
- field: 'warehouseName',
- title: '浠撳簱',
- minWidth: 100,
- },
- {
- field: 'locationName',
- title: '搴撳尯',
- minWidth: 100,
- },
- {
- field: 'areaName',
- title: '搴撲綅',
- minWidth: 100,
- },
- ...(editable
- ? [
- {
- title: '鎿嶄綔',
- width: 160,
- fixed: 'right',
- slots: { default: 'actions' },
- } as const,
- ]
- : []),
- ];
-}
-
-/** 鍏ュ簱鍗曡鏂板/淇敼鐨勮〃鍗� */
-export function useLineFormSchema(formApi?: VbenFormApi): VbenFormSchema[] {
- return [
- {
- fieldName: 'itemId',
- label: '鐗╂枡',
- component: markRaw(MdItemSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨鐗╂枡',
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'quantity',
- label: '鍏ュ簱鏁伴噺',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0.01,
- placeholder: '璇疯緭鍏ュ叆搴撴暟閲�',
- precision: 2,
- },
- rules: 'required',
- },
- {
- fieldName: 'batchCode',
- label: '鎵规鍙�',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ユ壒娆″彿',
- },
- },
- {
- fieldName: 'warehouseId',
- label: '浠撳簱',
- component: markRaw(WmWarehouseSelect),
- componentProps: {
- // 鍒囨崲浠撳簱鍚庢竻绌哄簱鍖哄拰搴撲綅
- onChange: async () => {
- await formApi?.setValues({
- areaId: undefined,
- locationId: undefined,
- });
- },
- placeholder: '璇烽�夋嫨浠撳簱',
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'locationId',
- label: '搴撳尯',
- component: markRaw(WmWarehouseLocationSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨搴撳尯',
- },
- rules: 'selectRequired',
- dependencies: {
- triggerFields: ['warehouseId'],
- componentProps: (values) => ({
- // 鍒囨崲搴撳尯鍚庢竻绌哄簱浣�
- onChange: async () => {
- await formApi?.setFieldValue('areaId', undefined);
- },
- placeholder: '璇烽�夋嫨搴撳尯',
- warehouseId: values.warehouseId,
- }),
- },
- },
- {
- fieldName: 'areaId',
- label: '搴撲綅',
- component: markRaw(WmWarehouseAreaSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨搴撲綅',
- },
- rules: 'selectRequired',
- dependencies: {
- triggerFields: ['locationId'],
- componentProps: (values) => ({
- locationId: values.locationId,
- placeholder: '璇烽�夋嫨搴撲綅',
- }),
- },
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
diff --git a/src/views/miscreceipt/index.vue b/src/views/miscreceipt/index.vue
deleted file mode 100644
index 6369376..0000000
--- a/src/views/miscreceipt/index.vue
+++ /dev/null
@@ -1,187 +0,0 @@
-<script lang="ts" setup>
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmMiscReceiptApi } from '#/api/mes/wm/miscreceipt';
-
-import { Page, useVbenModal } from '@vben/common-ui';
-import { MesWmMiscReceiptStatusEnum } from '@vben/constants';
-import { downloadFileFromBlobPart } from '@vben/utils';
-
-import { Button, message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import {
- cancelMiscReceipt,
- deleteMiscReceipt,
- exportMiscReceipt,
- getMiscReceiptPage,
-} from '#/api/mes/wm/miscreceipt';
-import { $t } from '#/locales';
-
-import { useGridColumns, useGridFormSchema } from './data';
-import Form from './modules/form.vue';
-
-const [FormModal, formModalApi] = useVbenModal({
- connectedComponent: Form,
- destroyOnClose: true,
-});
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- gridApi.query();
-}
-
-/** 鍒涘缓鏉傞」鍏ュ簱鍗� */
-function handleCreate() {
- formModalApi.setData({ formType: 'create' }).open();
-}
-
-/** 鏌ョ湅鏉傞」鍏ュ簱鍗� */
-function handleDetail(row: MesWmMiscReceiptApi.MiscReceipt) {
- formModalApi.setData({ formType: 'detail', id: row.id }).open();
-}
-
-/** 缂栬緫鏉傞」鍏ュ簱鍗� */
-function handleEdit(row: MesWmMiscReceiptApi.MiscReceipt) {
- formModalApi.setData({ formType: 'update', id: row.id }).open();
-}
-
-/** 鎵ц鍏ュ簱 */
-function handleFinish(row: MesWmMiscReceiptApi.MiscReceipt) {
- formModalApi.setData({ formType: 'finish', id: row.id }).open();
-}
-
-/** 鍒犻櫎鏉傞」鍏ュ簱鍗� */
-async function handleDelete(row: MesWmMiscReceiptApi.MiscReceipt) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.code]),
- duration: 0,
- });
- try {
- await deleteMiscReceipt(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.code]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-/** 鍙栨秷鏉傞」鍏ュ簱鍗� */
-async function handleCancel(row: MesWmMiscReceiptApi.MiscReceipt) {
- await cancelMiscReceipt(row.id!);
- message.success('鍙栨秷鎴愬姛');
- handleRefresh();
-}
-
-/** 瀵煎嚭琛ㄦ牸 */
-async function handleExport() {
- const data = await exportMiscReceipt(await gridApi.formApi.getValues());
- downloadFileFromBlobPart({ fileName: '鏉傞」鍏ュ簱鍗�.xls', source: data });
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- formOptions: {
- schema: useGridFormSchema(),
- },
- gridOptions: {
- columns: useGridColumns(),
- height: 'auto',
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }, formValues) => {
- return await getMiscReceiptPage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- ...formValues,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- search: true,
- },
- } as VxeTableGridOptions<MesWmMiscReceiptApi.MiscReceipt>,
-});
-</script>
-
-<template>
- <Page auto-content-height><FormModal @success="handleRefresh" />
-
- <Grid table-title="鏉傞」鍏ュ簱鍗曞垪琛�">
- <template #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: $t('ui.actionTitle.create', ['鏉傞」鍏ュ簱鍗�']),
- type: 'primary',
- icon: ACTION_ICON.ADD,
- auth: ['mes:wm:misc-receipt:create'],
- onClick: handleCreate,
- },
- {
- label: $t('ui.actionTitle.export'),
- type: 'primary',
- icon: ACTION_ICON.DOWNLOAD,
- auth: ['mes:wm:misc-receipt:export'],
- onClick: handleExport,
- },
- ]"
- />
- </template>
- <template #code="{ row }">
- <Button type="link" @click="handleDetail(row)">
- {{ row.code }}
- </Button>
- </template>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- auth: ['mes:wm:misc-receipt:update'],
- ifShow: row.status === MesWmMiscReceiptStatusEnum.PREPARE,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- auth: ['mes:wm:misc-receipt:delete'],
- ifShow: row.status === MesWmMiscReceiptStatusEnum.PREPARE,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.code]),
- confirm: handleDelete.bind(null, row),
- },
- },
- {
- label: '鎵ц鍏ュ簱',
- type: 'link',
- auth: ['mes:wm:misc-receipt:finish'],
- ifShow: row.status === MesWmMiscReceiptStatusEnum.APPROVED,
- onClick: handleFinish.bind(null, row),
- },
- {
- label: '鍙栨秷',
- type: 'link',
- danger: true,
- auth: ['mes:wm:misc-receipt:cancel'],
- ifShow: row.status === MesWmMiscReceiptStatusEnum.APPROVED,
- popConfirm: {
- title: '纭鍙栨秷璇ユ潅椤瑰叆搴撳崟鍚楋紵',
- confirm: handleCancel.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </Page>
-</template>
diff --git a/src/views/miscreceipt/modules/form.vue b/src/views/miscreceipt/modules/form.vue
deleted file mode 100644
index cfab99d..0000000
--- a/src/views/miscreceipt/modules/form.vue
+++ /dev/null
@@ -1,200 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { MesWmMiscReceiptApi } from '#/api/mes/wm/miscreceipt';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-import { MesWmMiscReceiptStatusEnum } from '@vben/constants';
-
-import { Button, Divider, message, Popconfirm } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createMiscReceipt,
- finishMiscReceipt,
- getMiscReceipt,
- submitMiscReceipt,
- updateMiscReceipt,
-} from '#/api/mes/wm/miscreceipt';
-import { $t } from '#/locales';
-
-import { useFormSchema } from '../data';
-import LineList from './line-list.vue';
-
-const emit = defineEmits(['success']);
-const formType = ref<FormType>('create');
-const formData = ref<MesWmMiscReceiptApi.MiscReceipt>();
-const originalSnapshot = ref(''); // 琛ㄥ崟鍘熷鏁版嵁蹇収锛岀敤浜庢彁浜ゆ椂璺宠繃鏈彉鏇寸殑淇濆瓨璇锋眰
-const isEditable = computed(() =>
- // 鏄惁涓虹紪杈戞ā寮忥紙鍙繚瀛橈級
- ['create', 'update'].includes(formType.value),
-);
-const isFinish = computed(() => formType.value === 'finish'); // 鏄惁涓烘墽琛屽叆搴撴ā寮�
-const canSubmit = computed(
- () =>
- // 鏄惁鍙彁浜�
- formType.value === 'update' &&
- formData.value?.status === MesWmMiscReceiptStatusEnum.PREPARE,
-);
-const getTitle = computed(() => {
- if (formType.value === 'detail') {
- return $t('ui.actionTitle.view', ['鏉傞」鍏ュ簱鍗�']);
- }
- if (formType.value === 'finish') {
- return '鎵ц鍏ュ簱';
- }
- return formType.value === 'update'
- ? $t('ui.actionTitle.edit', ['鏉傞」鍏ュ簱鍗�'])
- : $t('ui.actionTitle.create', ['鏉傞」鍏ュ簱鍗�']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 110,
- },
- layout: 'horizontal',
- schema: [],
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-/** 鎻愪氦鍏ュ簱鍗曪細琛ㄥ崟鏈変慨鏀规椂鍏堜繚瀛橈紝鍐嶈皟鐢ㄦ彁浜ゆ帴鍙� */
-async function handleSubmit() {
- const { valid } = await formApi.validate();
- if (!valid || !formData.value?.id) {
- return;
- }
- modalApi.lock();
- try {
- const current = JSON.stringify(await formApi.getValues());
- if (current !== originalSnapshot.value) {
- const data =
- (await formApi.getValues()) as MesWmMiscReceiptApi.MiscReceipt;
- await updateMiscReceipt({ ...formData.value, ...data });
- originalSnapshot.value = current;
- }
- await submitMiscReceipt(formData.value.id);
- message.success('鎻愪氦鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-/** 鎵ц鍏ュ簱 */
-async function handleFinish() {
- if (!formData.value?.id) {
- return;
- }
- modalApi.lock();
- try {
- await finishMiscReceipt(formData.value.id);
- message.success('鍏ュ簱鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- if (!isEditable.value) {
- await modalApi.close();
- return;
- }
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data = (await formApi.getValues()) as MesWmMiscReceiptApi.MiscReceipt;
- try {
- if (formData.value?.id) {
- await updateMiscReceipt({ ...formData.value, ...data });
- formData.value = { ...formData.value, ...data };
- } else {
- const id = await createMiscReceipt(data);
- formData.value = {
- ...data,
- id,
- status: MesWmMiscReceiptStatusEnum.PREPARE,
- };
- await formApi.setFieldValue('id', id);
- await formApi.setFieldValue('status', formData.value.status);
- formType.value = 'update';
- }
- originalSnapshot.value = JSON.stringify(await formApi.getValues());
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- originalSnapshot.value = '';
- return;
- }
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{ formType: FormType; id?: number }>();
- formType.value = data.formType;
- formApi.setState({ schema: useFormSchema(formType.value, formApi) });
- formApi.setDisabled(
- formType.value === 'detail' || formType.value === 'finish',
- );
- modalApi.setState({ showConfirmButton: isEditable.value });
- if (data?.id) {
- modalApi.lock();
- try {
- formData.value = await getMiscReceipt(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- }
- originalSnapshot.value = JSON.stringify(await formApi.getValues());
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- <!-- 闈炴柊寤烘ā寮忓睍绀虹墿鏂欎俊鎭� -->
- <template v-if="formData?.id">
- <Divider>鐗╂枡淇℃伅</Divider>
- <div class="mx-4">
- <LineList :form-type="formType" :receipt-id="formData.id" />
- </div>
- </template>
- <template #prepend-footer>
- <div class="flex flex-auto items-center gap-2">
- <Popconfirm
- v-if="canSubmit"
- title="纭鎻愪氦璇ユ潅椤瑰叆搴撳崟锛熴�愭彁浜ゅ悗灏嗕笉鑳戒慨鏀广��"
- @confirm="handleSubmit"
- >
- <Button type="primary">鎻愪氦</Button>
- </Popconfirm>
- <Popconfirm
- v-if="isFinish"
- title="纭鎵ц鍏ュ簱锛熸墽琛屽悗灏嗘洿鏂板簱瀛樺彴璐︺��"
- @confirm="handleFinish"
- >
- <Button type="primary">鎵ц鍏ュ簱</Button>
- </Popconfirm>
- </div>
- </template>
- </Modal>
-</template>
diff --git a/src/views/miscreceipt/modules/line-form.vue b/src/views/miscreceipt/modules/line-form.vue
deleted file mode 100644
index d660ba3..0000000
--- a/src/views/miscreceipt/modules/line-form.vue
+++ /dev/null
@@ -1,98 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmMiscReceiptLineApi } from '#/api/mes/wm/miscreceipt/line';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createMiscReceiptLine,
- getMiscReceiptLine,
- updateMiscReceiptLine,
-} from '#/api/mes/wm/miscreceipt/line';
-import { $t } from '#/locales';
-
-import { useLineFormSchema } from '../data';
-
-const emit = defineEmits(['success']);
-const formData = ref<MesWmMiscReceiptLineApi.MiscReceiptLine>();
-const receiptId = ref<number>(); // 鎵�灞炲叆搴撳崟缂栧彿
-
-const getTitle = computed(() => {
- return formData.value?.id
- ? $t('ui.actionTitle.edit', ['鐗╂枡'])
- : $t('ui.actionTitle.create', ['鐗╂枡']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 90,
- },
- layout: 'horizontal',
- schema: useLineFormSchema(),
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data =
- (await formApi.getValues()) as MesWmMiscReceiptLineApi.MiscReceiptLine;
- data.receiptId = receiptId.value;
- try {
- await (formData.value?.id
- ? updateMiscReceiptLine({ ...data, id: formData.value.id })
- : createMiscReceiptLine(data));
- // 鍏抽棴骞舵彁绀�
- await modalApi.close();
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- return;
- }
- formApi.setState({ schema: useLineFormSchema(formApi) });
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{
- id?: number;
- receiptId: number;
- }>();
- receiptId.value = data.receiptId;
- if (!data.id) {
- return;
- }
- modalApi.lock();
- try {
- formData.value = await getMiscReceiptLine(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- </Modal>
-</template>
diff --git a/src/views/miscreceipt/modules/line-list.vue b/src/views/miscreceipt/modules/line-list.vue
deleted file mode 100644
index d07ee77..0000000
--- a/src/views/miscreceipt/modules/line-list.vue
+++ /dev/null
@@ -1,140 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmMiscReceiptLineApi } from '#/api/mes/wm/miscreceipt/line';
-
-import { computed } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import {
- deleteMiscReceiptLine,
- getMiscReceiptLineListByReceiptId,
-} from '#/api/mes/wm/miscreceipt/line';
-import { $t } from '#/locales';
-
-import { useLineGridColumns } from '../data';
-import LineForm from './line-form.vue';
-
-const props = defineProps<{
- formType: FormType;
- receiptId: number;
-}>();
-
-const isEditable = computed(() =>
- // 鏄惁鍙紪杈戞槑缁嗚
- ['create', 'update'].includes(props.formType),
-);
-
-const [LineFormModal, lineFormModalApi] = useVbenModal({
- connectedComponent: LineForm,
- destroyOnClose: true,
-});
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- gridApi.query();
-}
-
-/** 娣诲姞鐗╂枡 */
-function handleCreate() {
- lineFormModalApi.setData({ receiptId: props.receiptId }).open();
-}
-
-/** 缂栬緫鐗╂枡 */
-function handleEdit(row: MesWmMiscReceiptLineApi.MiscReceiptLine) {
- lineFormModalApi.setData({ id: row.id, receiptId: props.receiptId }).open();
-}
-
-/** 鍒犻櫎鐗╂枡 */
-async function handleDelete(row: MesWmMiscReceiptLineApi.MiscReceiptLine) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.itemName]),
- duration: 0,
- });
- try {
- await deleteMiscReceiptLine(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.itemName]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- gridOptions: {
- columns: useLineGridColumns(isEditable.value),
- height: 360,
- keepSource: true,
- pagerConfig: {
- enabled: false,
- },
- proxyConfig: {
- ajax: {
- query: async () => {
- if (!props.receiptId) {
- return { list: [], total: 0 };
- }
- const list = await getMiscReceiptLineListByReceiptId(props.receiptId);
- return { list, total: list.length };
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- },
- } as VxeTableGridOptions<MesWmMiscReceiptLineApi.MiscReceiptLine>,
-});
-</script>
-
-<template>
- <div>
- <LineFormModal @success="handleRefresh" />
- <Grid table-title="鐗╂枡淇℃伅">
- <template v-if="isEditable" #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: '娣诲姞鐗╂枡',
- type: 'primary',
- icon: ACTION_ICON.ADD,
- onClick: handleCreate,
- },
- ]"
- />
- </template>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- ifShow: isEditable,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- ifShow: isEditable,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.itemName]),
- confirm: handleDelete.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </div>
-</template>
diff --git a/src/views/outsourceissue/data.ts b/src/views/outsourceissue/data.ts
deleted file mode 100644
index ddd8661..0000000
--- a/src/views/outsourceissue/data.ts
+++ /dev/null
@@ -1,487 +0,0 @@
-锘縤mport type { VbenFormApi, VbenFormSchema } from '#/adapter/form';
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesProWorkOrderApi } from '#/api/mes/pro/workorder';
-import type { MesWmMaterialStockApi } from '#/api/mes/wm/materialstock';
-import type { MesWmOutsourceIssueApi } from '#/api/mes/wm/outsourceissue';
-import type { MesWmOutsourceIssueDetailApi } from '#/api/mes/wm/outsourceissue/detail';
-import type { MesWmOutsourceIssueLineApi } from '#/api/mes/wm/outsourceissue/line';
-
-import { h, markRaw } from 'vue';
-
-import {
- DICT_TYPE,
- MesAutoCodeRuleCode,
- MesProWorkOrderStatusEnum,
- MesProWorkOrderTypeEnum,
-} from '@vben/constants';
-
-import { Button } from 'ant-design-vue';
-
-import { generateAutoCode } from '#/api/mes/md/autocode/record';
-import { getRangePickerDefaultProps } from '#/utils';
-import { MdItemSelect } from '#/views/mes/md/item/components';
-import { MdVendorSelect } from '#/views/mes/md/vendor/components';
-import { ProWorkOrderSelect } from '#/views/mes/pro/workorder/components';
-import { WmMaterialStockSelect } from '#/views/wls/materialstock/components';
-import {
- WmWarehouseAreaSelect,
- WmWarehouseLocationSelect,
- WmWarehouseSelect,
-} from '#/views/wls/warehouse/components';
-
-/** 琛ㄥ崟绫诲瀷 */
-export type FormType = 'create' | 'detail' | 'finish' | 'stock' | 'update';
-
-/** 琛ㄥ崟澶撮儴鏄惁鍙锛堟嫞璐с�佽鎯呫�侀鍑烘�侊級 */
-function isHeaderReadonly(formType: FormType): boolean {
- return formType === 'detail' || formType === 'finish' || formType === 'stock';
-}
-
-/** 鏂板/淇敼鐨勮〃鍗� */
-export function useFormSchema(
- formType: FormType,
- formApi?: VbenFormApi,
-): VbenFormSchema[] {
- return [
- {
- fieldName: 'id',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'status',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'code',
- label: '鍙戞枡鍗曠紪鍙�',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ュ彂鏂欏崟缂栧彿',
- },
- rules: 'required',
- suffix: isHeaderReadonly(formType)
- ? undefined
- : () =>
- h(
- Button,
- {
- type: 'default',
- onClick: async () => {
- const code = await generateAutoCode(
- MesAutoCodeRuleCode.WM_OUTSOURCE_ISSUE_CODE,
- );
- await formApi?.setFieldValue('code', code);
- },
- },
- { default: () => '鐢熸垚' },
- ),
- },
- {
- fieldName: 'name',
- label: '鍙戞枡鍗曞悕绉�',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ュ彂鏂欏崟鍚嶇О',
- },
- rules: 'required',
- },
- {
- fieldName: 'issueDate',
- label: '鍙戞枡鏃ユ湡',
- component: 'DatePicker',
- componentProps: {
- format: 'YYYY-MM-DD',
- placeholder: '璇烽�夋嫨鍙戞枡鏃ユ湡',
- valueFormat: 'x',
- },
- },
- {
- fieldName: 'workOrderId',
- label: '澶栧崗璁㈠崟',
- component: markRaw(ProWorkOrderSelect),
- componentProps: {
- // 閫夋嫨澶栧崗璁㈠崟鍚庯紝鑷姩鍥炲~渚涘簲鍟�
- onChange: async (workOrder?: MesProWorkOrderApi.WorkOrder) => {
- await formApi?.setFieldValue('vendorId', workOrder?.vendorId);
- },
- status: MesProWorkOrderStatusEnum.CONFIRMED,
- type: MesProWorkOrderTypeEnum.OUTSOURCE,
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'vendorId',
- label: '渚涘簲鍟�',
- component: markRaw(MdVendorSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨渚涘簲鍟�',
- },
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勬悳绱㈣〃鍗� */
-export function useGridFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'code',
- label: '鍙戞枡鍗曠紪鍙�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ュ彂鏂欏崟缂栧彿',
- },
- },
- {
- fieldName: 'name',
- label: '鍙戞枡鍗曞悕绉�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ュ彂鏂欏崟鍚嶇О',
- },
- },
- {
- fieldName: 'vendorId',
- label: '渚涘簲鍟�',
- component: markRaw(MdVendorSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨渚涘簲鍟�',
- },
- },
- {
- fieldName: 'issueDate',
- label: '鍙戞枡鏃ユ湡',
- component: 'RangePicker',
- componentProps: {
- ...getRangePickerDefaultProps(),
- allowClear: true,
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勫瓧娈� */
-export function useGridColumns(): VxeTableGridOptions<MesWmOutsourceIssueApi.OutsourceIssue>['columns'] {
- return [
- {
- field: 'code',
- title: '鍙戞枡鍗曠紪鍙�',
- minWidth: 160,
- slots: { default: 'code' },
- },
- {
- field: 'name',
- title: '鍙戞枡鍗曞悕绉�',
- minWidth: 150,
- },
- {
- field: 'workOrderCode',
- title: '鐢熶骇璁㈠崟鍙�',
- minWidth: 140,
- },
- {
- field: 'vendorName',
- title: '渚涘簲鍟嗗悕绉�',
- minWidth: 120,
- },
- {
- field: 'issueDate',
- title: '鍙戞枡鏃ユ湡',
- width: 180,
- formatter: 'formatDate',
- },
- {
- field: 'status',
- title: '鍗曟嵁鐘舵��',
- minWidth: 100,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_OUTSOURCE_ISSUE_STATUS },
- },
- },
- {
- title: '鎿嶄綔',
- width: 240,
- fixed: 'right',
- slots: { default: 'actions' },
- },
- ];
-}
-
-/** 鍙戞枡鍗曡瀛愯〃鐨勫瓧娈� */
-export function useLineGridColumns(
- editable: boolean,
- stockable: boolean,
-): VxeTableGridOptions<MesWmOutsourceIssueLineApi.OutsourceIssueLine>['columns'] {
- return [
- {
- type: 'expand',
- width: 48,
- slots: { content: 'detail' },
- },
- {
- field: 'itemCode',
- title: '鐗╂枡缂栫爜',
- minWidth: 120,
- },
- {
- field: 'itemName',
- title: '鐗╂枡鍚嶇О',
- minWidth: 140,
- },
- {
- field: 'specification',
- title: '瑙勬牸鍨嬪彿',
- minWidth: 120,
- },
- {
- field: 'unitMeasureName',
- title: '鍗曚綅',
- width: 80,
- },
- {
- field: 'quantity',
- title: '棰嗘枡鏁伴噺',
- width: 100,
- },
- {
- field: 'batchCode',
- title: '鎵规鍙�',
- minWidth: 120,
- },
- {
- field: 'remark',
- title: '澶囨敞',
- minWidth: 150,
- },
- ...(editable || stockable
- ? [
- {
- title: '鎿嶄綔',
- width: 160,
- fixed: 'right',
- slots: { default: 'actions' },
- } as const,
- ]
- : []),
- ];
-}
-
-/** 鍙戞枡鍗曡鏂板/淇敼鐨勮〃鍗� */
-export function useLineFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'itemId',
- label: '鐗╂枡',
- component: markRaw(MdItemSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨鐗╂枡',
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'quantity',
- label: '鍙戞枡鏁伴噺',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0,
- placeholder: '璇疯緭鍏ュ彂鏂欐暟閲�',
- precision: 2,
- },
- rules: 'required',
- },
- {
- fieldName: 'batchCode',
- label: '鎵规鍙�',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ユ壒娆″彿',
- },
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
-
-/** 鍙戞枡鏄庣粏瀛愯〃鐨勫瓧娈� */
-export function useDetailGridColumns(
- stockable: boolean,
-): VxeTableGridOptions<MesWmOutsourceIssueDetailApi.OutsourceIssueDetail>['columns'] {
- return [
- {
- field: 'warehouseName',
- title: '浠撳簱鍚嶇О',
- minWidth: 100,
- },
- {
- field: 'locationName',
- title: '搴撳尯鍚嶇О',
- minWidth: 100,
- },
- {
- field: 'areaName',
- title: '搴撲綅鍚嶇О',
- minWidth: 100,
- },
- {
- field: 'quantity',
- title: '鏁伴噺',
- width: 100,
- },
- ...(stockable
- ? [
- {
- title: '鎿嶄綔',
- width: 120,
- fixed: 'right',
- slots: { default: 'actions' },
- } as const,
- ]
- : []),
- ];
-}
-
-/** 鍙戞枡鏄庣粏鏂板/淇敼鐨勮〃鍗� */
-export function useDetailFormSchema(formApi?: VbenFormApi): VbenFormSchema[] {
- return [
- {
- fieldName: 'quantityMax',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'materialStockId',
- label: '搴撳瓨璁板綍',
- component: markRaw(WmMaterialStockSelect),
- componentProps: {
- // 閫夋嫨搴撳瓨璁板綍鍚庯紝鑷姩鍥炲~浠撳簱/搴撳尯/搴撲綅/鎵规/鏁伴噺
- onChange: async (stock?: MesWmMaterialStockApi.MaterialStock) => {
- await formApi?.setValues({
- areaId: stock?.areaId,
- batchCode: stock?.batchCode,
- batchId: stock?.batchId,
- locationId: stock?.locationId,
- quantity: stock?.quantity,
- quantityMax: stock?.quantity,
- warehouseId: stock?.warehouseId,
- });
- },
- },
- rules: 'selectRequired',
- dependencies: {
- triggerFields: ['itemId'],
- componentProps: (values) => ({
- itemId: values.itemId,
- }),
- },
- },
- {
- fieldName: 'itemId',
- label: '鐗╂枡',
- component: markRaw(MdItemSelect),
- componentProps: {
- disabled: true,
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'quantity',
- label: '鏁伴噺',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0,
- placeholder: '璇疯緭鍏ユ暟閲�',
- precision: 2,
- },
- rules: 'required',
- dependencies: {
- triggerFields: ['quantityMax'],
- componentProps: (values) => ({
- class: '!w-full',
- max: values.quantityMax,
- min: 0,
- placeholder: '璇疯緭鍏ユ暟閲�',
- precision: 2,
- }),
- },
- },
- {
- fieldName: 'warehouseId',
- label: '鍙戞枡浠撳簱',
- component: markRaw(WmWarehouseSelect),
- componentProps: {
- disabled: true,
- },
- },
- {
- fieldName: 'locationId',
- label: '搴撳尯',
- component: markRaw(WmWarehouseLocationSelect),
- componentProps: {
- disabled: true,
- },
- dependencies: {
- triggerFields: ['warehouseId'],
- componentProps: (values) => ({
- disabled: true,
- warehouseId: values.warehouseId,
- }),
- },
- },
- {
- fieldName: 'areaId',
- label: '搴撲綅',
- component: markRaw(WmWarehouseAreaSelect),
- componentProps: {
- disabled: true,
- },
- dependencies: {
- triggerFields: ['locationId'],
- componentProps: (values) => ({
- disabled: true,
- locationId: values.locationId,
- }),
- },
- },
- {
- fieldName: 'batchCode',
- label: '鎵规鍙�',
- component: 'Input',
- componentProps: {
- disabled: true,
- },
- },
- ];
-}
diff --git a/src/views/outsourceissue/index.vue b/src/views/outsourceissue/index.vue
deleted file mode 100644
index 059b62e..0000000
--- a/src/views/outsourceissue/index.vue
+++ /dev/null
@@ -1,201 +0,0 @@
-<script lang="ts" setup>
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmOutsourceIssueApi } from '#/api/mes/wm/outsourceissue';
-
-import { Page, useVbenModal } from '@vben/common-ui';
-import { MesWmOutsourceIssueStatusEnum } from '@vben/constants';
-import { downloadFileFromBlobPart } from '@vben/utils';
-
-import { Button, message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import {
- cancelOutsourceIssue,
- deleteOutsourceIssue,
- exportOutsourceIssue,
- getOutsourceIssuePage,
-} from '#/api/mes/wm/outsourceissue';
-import { $t } from '#/locales';
-
-import { useGridColumns, useGridFormSchema } from './data';
-import Form from './modules/form.vue';
-
-const [FormModal, formModalApi] = useVbenModal({
- connectedComponent: Form,
- destroyOnClose: true,
-});
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- gridApi.query();
-}
-
-/** 鍒涘缓澶栧崗鍙戞枡鍗� */
-function handleCreate() {
- formModalApi.setData({ formType: 'create' }).open();
-}
-
-/** 鏌ョ湅澶栧崗鍙戞枡鍗� */
-function handleDetail(row: MesWmOutsourceIssueApi.OutsourceIssue) {
- formModalApi.setData({ formType: 'detail', id: row.id }).open();
-}
-
-/** 缂栬緫澶栧崗鍙戞枡鍗� */
-function handleEdit(row: MesWmOutsourceIssueApi.OutsourceIssue) {
- formModalApi.setData({ formType: 'update', id: row.id }).open();
-}
-
-/** 鎵ц鎷h揣 */
-function handleStock(row: MesWmOutsourceIssueApi.OutsourceIssue) {
- formModalApi.setData({ formType: 'stock', id: row.id }).open();
-}
-
-/** 鎵ц棰嗗嚭 */
-function handleFinish(row: MesWmOutsourceIssueApi.OutsourceIssue) {
- formModalApi.setData({ formType: 'finish', id: row.id }).open();
-}
-
-/** 鍒犻櫎澶栧崗鍙戞枡鍗� */
-async function handleDelete(row: MesWmOutsourceIssueApi.OutsourceIssue) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.code]),
- duration: 0,
- });
- try {
- await deleteOutsourceIssue(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.code]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-/** 鍙栨秷澶栧崗鍙戞枡鍗� */
-async function handleCancel(row: MesWmOutsourceIssueApi.OutsourceIssue) {
- await cancelOutsourceIssue(row.id!);
- message.success('鍙栨秷鎴愬姛');
- handleRefresh();
-}
-
-/** 瀵煎嚭琛ㄦ牸 */
-async function handleExport() {
- const data = await exportOutsourceIssue(await gridApi.formApi.getValues());
- downloadFileFromBlobPart({ fileName: '澶栧崗鍙戞枡鍗�.xls', source: data });
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- formOptions: {
- schema: useGridFormSchema(),
- },
- gridOptions: {
- columns: useGridColumns(),
- height: 'auto',
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }, formValues) => {
- return await getOutsourceIssuePage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- ...formValues,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- search: true,
- },
- } as VxeTableGridOptions<MesWmOutsourceIssueApi.OutsourceIssue>,
-});
-</script>
-
-<template>
- <Page auto-content-height><FormModal @success="handleRefresh" />
-
- <Grid table-title="澶栧崗鍙戞枡鍗曞垪琛�">
- <template #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: $t('ui.actionTitle.create', ['澶栧崗鍙戞枡鍗�']),
- type: 'primary',
- icon: ACTION_ICON.ADD,
- auth: ['mes:wm-outsource-issue:create'],
- onClick: handleCreate,
- },
- {
- label: $t('ui.actionTitle.export'),
- type: 'primary',
- icon: ACTION_ICON.DOWNLOAD,
- auth: ['mes:wm-outsource-issue:export'],
- onClick: handleExport,
- },
- ]"
- />
- </template>
- <template #code="{ row }">
- <Button type="link" @click="handleDetail(row)">
- {{ row.code }}
- </Button>
- </template>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- auth: ['mes:wm-outsource-issue:update'],
- ifShow: row.status === MesWmOutsourceIssueStatusEnum.PREPARE,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- auth: ['mes:wm-outsource-issue:delete'],
- ifShow: row.status === MesWmOutsourceIssueStatusEnum.PREPARE,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.code]),
- confirm: handleDelete.bind(null, row),
- },
- },
- {
- label: '鎵ц鎷h揣',
- type: 'link',
- auth: ['mes:wm-outsource-issue:update'],
- ifShow: row.status === MesWmOutsourceIssueStatusEnum.APPROVING,
- onClick: handleStock.bind(null, row),
- },
- {
- label: '鎵ц棰嗗嚭',
- type: 'link',
- auth: ['mes:wm-outsource-issue:finish'],
- ifShow: row.status === MesWmOutsourceIssueStatusEnum.APPROVED,
- onClick: handleFinish.bind(null, row),
- },
- {
- label: '鍙栨秷',
- type: 'link',
- danger: true,
- auth: ['mes:wm-outsource-issue:update'],
- ifShow:
- row.status === MesWmOutsourceIssueStatusEnum.APPROVING ||
- row.status === MesWmOutsourceIssueStatusEnum.APPROVED,
- popConfirm: {
- title: '纭鍙栨秷璇ュ鍗忓彂鏂欏崟锛熷彇娑堝悗涓嶅彲鎭㈠銆�',
- confirm: handleCancel.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </Page>
-</template>
diff --git a/src/views/outsourceissue/modules/detail-form.vue b/src/views/outsourceissue/modules/detail-form.vue
deleted file mode 100644
index 16504ff..0000000
--- a/src/views/outsourceissue/modules/detail-form.vue
+++ /dev/null
@@ -1,104 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmOutsourceIssueDetailApi } from '#/api/mes/wm/outsourceissue/detail';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createOutsourceIssueDetail,
- getOutsourceIssueDetail,
- updateOutsourceIssueDetail,
-} from '#/api/mes/wm/outsourceissue/detail';
-import { $t } from '#/locales';
-
-import { useDetailFormSchema } from '../data';
-
-const emit = defineEmits<{ success: [lineId: number] }>();
-const formData = ref<MesWmOutsourceIssueDetailApi.OutsourceIssueDetail>();
-const issueId = ref<number>(); // 鎵�灞炲彂鏂欏崟缂栧彿
-const lineId = ref<number>(); // 鎵�灞炲彂鏂欏崟琛岀紪鍙�
-
-const getTitle = computed(() => {
- return formData.value?.id
- ? $t('ui.actionTitle.edit', ['鍙戞枡鏄庣粏'])
- : $t('ui.actionTitle.create', ['鍙戞枡鏄庣粏']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 90,
- },
- layout: 'horizontal',
- schema: useDetailFormSchema(),
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data =
- (await formApi.getValues()) as MesWmOutsourceIssueDetailApi.OutsourceIssueDetail;
- data.issueId = issueId.value;
- data.lineId = lineId.value;
- try {
- await (formData.value?.id
- ? updateOutsourceIssueDetail({ ...data, id: formData.value.id })
- : createOutsourceIssueDetail(data));
- // 鍏抽棴骞舵彁绀�
- await modalApi.close();
- emit('success', lineId.value!);
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- return;
- }
- formApi.setState({ schema: useDetailFormSchema(formApi) });
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{
- detailId?: number;
- issueId: number;
- itemId?: number;
- lineId: number;
- }>();
- issueId.value = data.issueId;
- lineId.value = data.lineId;
- if (data.detailId) {
- modalApi.lock();
- try {
- formData.value = await getOutsourceIssueDetail(data.detailId);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- } else if (data.itemId) {
- await formApi.setFieldValue('itemId', data.itemId);
- }
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- </Modal>
-</template>
diff --git a/src/views/outsourceissue/modules/detail-list.vue b/src/views/outsourceissue/modules/detail-list.vue
deleted file mode 100644
index 13033cd..0000000
--- a/src/views/outsourceissue/modules/detail-list.vue
+++ /dev/null
@@ -1,105 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmOutsourceIssueDetailApi } from '#/api/mes/wm/outsourceissue/detail';
-
-import { computed, watch } from 'vue';
-
-import { message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import { deleteOutsourceIssueDetail } from '#/api/mes/wm/outsourceissue/detail';
-import { $t } from '#/locales';
-
-import { useDetailGridColumns } from '../data';
-
-const props = defineProps<{
- details: MesWmOutsourceIssueDetailApi.OutsourceIssueDetail[];
- formType: FormType;
-}>();
-
-const emit = defineEmits<{
- edit: [detailId: number];
- refresh: [];
-}>();
-
-const isStock = computed(() => props.formType === 'stock'); // 鏄惁涓烘嫞璐фā寮�
-
-/** 缂栬緫鍙戞枡鏄庣粏 */
-function handleEdit(row: MesWmOutsourceIssueDetailApi.OutsourceIssueDetail) {
- emit('edit', row.id!);
-}
-
-/** 鍒犻櫎鍙戞枡鏄庣粏 */
-async function handleDelete(
- row: MesWmOutsourceIssueDetailApi.OutsourceIssueDetail,
-) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.warehouseName]),
- duration: 0,
- });
- try {
- await deleteOutsourceIssueDetail(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.warehouseName]));
- emit('refresh');
- } finally {
- hideLoading();
- }
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- gridOptions: {
- border: true,
- columns: useDetailGridColumns(isStock.value),
- data: props.details,
- pagerConfig: {
- enabled: false,
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- size: 'small',
- toolbarConfig: {
- enabled: false,
- },
- } as VxeTableGridOptions<MesWmOutsourceIssueDetailApi.OutsourceIssueDetail>,
-});
-
-watch(
- () => props.details,
- (details) => gridApi.setGridOptions({ data: details }),
-);
-</script>
-
-<template>
- <div class="px-4 py-2">
- <Grid>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [
- row.warehouseName,
- ]),
- confirm: handleDelete.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </div>
-</template>
diff --git a/src/views/outsourceissue/modules/form.vue b/src/views/outsourceissue/modules/form.vue
deleted file mode 100644
index 752b076..0000000
--- a/src/views/outsourceissue/modules/form.vue
+++ /dev/null
@@ -1,236 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { MesWmOutsourceIssueApi } from '#/api/mes/wm/outsourceissue';
-
-import { computed, ref } from 'vue';
-
-import { confirm, useVbenModal } from '@vben/common-ui';
-import { MesWmOutsourceIssueStatusEnum } from '@vben/constants';
-
-import { Button, Divider, message, Popconfirm } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- checkOutsourceIssueQuantity,
- createOutsourceIssue,
- finishOutsourceIssue,
- getOutsourceIssue,
- stockOutsourceIssue,
- submitOutsourceIssue,
- updateOutsourceIssue,
-} from '#/api/mes/wm/outsourceissue';
-import { $t } from '#/locales';
-
-import { useFormSchema } from '../data';
-import LineList from './line-list.vue';
-
-const emit = defineEmits(['success']);
-const formType = ref<FormType>('create');
-const formData = ref<MesWmOutsourceIssueApi.OutsourceIssue>();
-const originalSnapshot = ref(''); // 琛ㄥ崟鍘熷鏁版嵁蹇収锛岀敤浜庢彁浜ゆ椂璺宠繃鏈彉鏇寸殑淇濆瓨璇锋眰
-const isEditable = computed(() =>
- // 鏄惁涓虹紪杈戞ā寮忥紙鍙繚瀛橈級
- ['create', 'update'].includes(formType.value),
-);
-const isStock = computed(() => formType.value === 'stock'); // 鏄惁涓烘嫞璐фā寮�
-const isFinish = computed(() => formType.value === 'finish'); // 鏄惁涓烘墽琛岄鍑烘ā寮�
-const canSubmit = computed(
- () =>
- // 鏄惁鍙彁浜�
- formType.value === 'update' &&
- formData.value?.status === MesWmOutsourceIssueStatusEnum.PREPARE,
-);
-const getTitle = computed(() => {
- if (formType.value === 'detail') {
- return $t('ui.actionTitle.view', ['澶栧崗鍙戞枡鍗�']);
- }
- if (formType.value === 'stock') {
- return '鎵ц鎷h揣';
- }
- if (formType.value === 'finish') {
- return '鎵ц棰嗗嚭';
- }
- return formType.value === 'update'
- ? $t('ui.actionTitle.edit', ['澶栧崗鍙戞枡鍗�'])
- : $t('ui.actionTitle.create', ['澶栧崗鍙戞枡鍗�']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 110,
- },
- layout: 'horizontal',
- schema: [],
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-/** 鎻愪氦鍙戞枡鍗曪細琛ㄥ崟鏈変慨鏀规椂鍏堜繚瀛橈紝鍐嶈皟鐢ㄦ彁浜ゆ帴鍙� */
-async function handleSubmit() {
- const { valid } = await formApi.validate();
- if (!valid || !formData.value?.id) {
- return;
- }
- modalApi.lock();
- try {
- const current = JSON.stringify(await formApi.getValues());
- if (current !== originalSnapshot.value) {
- const data =
- (await formApi.getValues()) as MesWmOutsourceIssueApi.OutsourceIssue;
- await updateOutsourceIssue({ ...formData.value, ...data });
- originalSnapshot.value = current;
- }
- await submitOutsourceIssue(formData.value.id);
- message.success('鎻愪氦鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-/** 鎵ц鎷h揣锛氭嫞璐ф暟閲忎笌鍙戞枡鏁伴噺涓嶄竴鑷存椂浜屾纭 */
-async function handleStock() {
- if (!formData.value?.id) {
- return;
- }
- const quantityMatch = await checkOutsourceIssueQuantity(formData.value.id);
- if (!quantityMatch) {
- try {
- await confirm('鍙戞枡鏁伴噺涓庢嫞璐ф暟閲忎笉涓�鑷达紝纭鎵ц鎷h揣锛�');
- } catch {
- return;
- }
- }
- modalApi.lock();
- try {
- await stockOutsourceIssue(formData.value.id);
- message.success('鎷h揣鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-/** 鎵ц棰嗗嚭 */
-async function handleFinish() {
- if (!formData.value?.id) {
- return;
- }
- modalApi.lock();
- try {
- await finishOutsourceIssue(formData.value.id);
- message.success('棰嗗嚭鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- if (!isEditable.value) {
- await modalApi.close();
- return;
- }
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data =
- (await formApi.getValues()) as MesWmOutsourceIssueApi.OutsourceIssue;
- try {
- if (formData.value?.id) {
- await updateOutsourceIssue({ ...formData.value, ...data });
- formData.value = { ...formData.value, ...data };
- } else {
- const id = await createOutsourceIssue(data);
- formData.value = {
- ...data,
- id,
- status: MesWmOutsourceIssueStatusEnum.PREPARE,
- };
- await formApi.setFieldValue('id', id);
- await formApi.setFieldValue('status', formData.value.status);
- formType.value = 'update';
- }
- originalSnapshot.value = JSON.stringify(await formApi.getValues());
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- originalSnapshot.value = '';
- return;
- }
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{ formType: FormType; id?: number }>();
- formType.value = data.formType;
- formApi.setState({ schema: useFormSchema(formType.value, formApi) });
- formApi.setDisabled(!isEditable.value);
- modalApi.setState({ showConfirmButton: isEditable.value });
- if (data?.id) {
- modalApi.lock();
- try {
- formData.value = await getOutsourceIssue(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- }
- originalSnapshot.value = JSON.stringify(await formApi.getValues());
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- <!-- 闈炴柊寤烘ā寮忓睍绀虹墿鏂欎俊鎭� -->
- <template v-if="formData?.id">
- <Divider>鐗╂枡淇℃伅</Divider>
- <div class="mx-4">
- <LineList :form-type="formType" :issue-id="formData.id" />
- </div>
- </template>
- <template #prepend-footer>
- <div class="flex flex-auto items-center gap-2">
- <Popconfirm
- v-if="canSubmit"
- title="纭鎻愪氦璇ュ鍗忓彂鏂欏崟锛熴�愭彁浜ゅ悗灏嗕笉鑳戒慨鏀广��"
- @confirm="handleSubmit"
- >
- <Button type="primary">鎻愪氦</Button>
- </Popconfirm>
- <Popconfirm
- v-if="isStock"
- title="纭鎵ц鎷h揣锛�"
- @confirm="handleStock"
- >
- <Button type="primary">鎵ц鎷h揣</Button>
- </Popconfirm>
- <Popconfirm
- v-if="isFinish"
- title="纭鎵ц棰嗗嚭锛熸墽琛屽悗灏嗘墸鍑忓簱瀛橈紝涓旀棤娉曟挙閿�銆�"
- @confirm="handleFinish"
- >
- <Button type="primary">鎵ц棰嗗嚭</Button>
- </Popconfirm>
- </div>
- </template>
- </Modal>
-</template>
diff --git a/src/views/outsourceissue/modules/line-form.vue b/src/views/outsourceissue/modules/line-form.vue
deleted file mode 100644
index b0f8f6d..0000000
--- a/src/views/outsourceissue/modules/line-form.vue
+++ /dev/null
@@ -1,97 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmOutsourceIssueLineApi } from '#/api/mes/wm/outsourceissue/line';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createOutsourceIssueLine,
- getOutsourceIssueLine,
- updateOutsourceIssueLine,
-} from '#/api/mes/wm/outsourceissue/line';
-import { $t } from '#/locales';
-
-import { useLineFormSchema } from '../data';
-
-const emit = defineEmits(['success']);
-const formData = ref<MesWmOutsourceIssueLineApi.OutsourceIssueLine>();
-const issueId = ref<number>(); // 鎵�灞炲彂鏂欏崟缂栧彿
-
-const getTitle = computed(() => {
- return formData.value?.id
- ? $t('ui.actionTitle.edit', ['鐗╂枡鍙戞枡鍗曡'])
- : $t('ui.actionTitle.create', ['鐗╂枡鍙戞枡鍗曡']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 90,
- },
- layout: 'horizontal',
- schema: useLineFormSchema(),
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data =
- (await formApi.getValues()) as MesWmOutsourceIssueLineApi.OutsourceIssueLine;
- data.issueId = issueId.value;
- try {
- await (formData.value?.id
- ? updateOutsourceIssueLine({ ...data, id: formData.value.id })
- : createOutsourceIssueLine(data));
- // 鍏抽棴骞舵彁绀�
- await modalApi.close();
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- return;
- }
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{
- id?: number;
- issueId: number;
- }>();
- issueId.value = data.issueId;
- if (!data.id) {
- return;
- }
- modalApi.lock();
- try {
- formData.value = await getOutsourceIssueLine(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- </Modal>
-</template>
diff --git a/src/views/outsourceissue/modules/line-list.vue b/src/views/outsourceissue/modules/line-list.vue
deleted file mode 100644
index 8341c02..0000000
--- a/src/views/outsourceissue/modules/line-list.vue
+++ /dev/null
@@ -1,227 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmOutsourceIssueDetailApi } from '#/api/mes/wm/outsourceissue/detail';
-import type { MesWmOutsourceIssueLineApi } from '#/api/mes/wm/outsourceissue/line';
-
-import { computed, reactive } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import { getOutsourceIssueDetailListByLineId } from '#/api/mes/wm/outsourceissue/detail';
-import {
- deleteOutsourceIssueLine,
- getOutsourceIssueLinePage,
-} from '#/api/mes/wm/outsourceissue/line';
-import { $t } from '#/locales';
-
-import { useLineGridColumns } from '../data';
-import DetailForm from './detail-form.vue';
-import DetailList from './detail-list.vue';
-import LineForm from './line-form.vue';
-
-const props = defineProps<{
- formType: FormType;
- issueId: number;
-}>();
-
-const isEditable = computed(() =>
- // 鏄惁鍙紪杈戞槑缁嗚
- ['create', 'update'].includes(props.formType),
-);
-const isStock = computed(() => props.formType === 'stock'); // 鏄惁涓烘嫞璐фā寮�
-const detailMap = reactive<
- Record<number, MesWmOutsourceIssueDetailApi.OutsourceIssueDetail[]>
->({}); // 宸插睍寮�琛岀殑鍙戞枡鏄庣粏缂撳瓨
-
-const [LineFormModal, lineFormModalApi] = useVbenModal({
- connectedComponent: LineForm,
- destroyOnClose: true,
-});
-
-const [DetailFormModal, detailFormModalApi] = useVbenModal({
- connectedComponent: DetailForm,
- destroyOnClose: true,
-});
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- for (const id of Object.keys(detailMap)) {
- delete detailMap[Number(id)];
- }
- gridApi.query();
-}
-
-/** 娣诲姞鐗╂枡 */
-function handleCreate() {
- lineFormModalApi.setData({ issueId: props.issueId }).open();
-}
-
-/** 缂栬緫鐗╂枡 */
-function handleEdit(row: MesWmOutsourceIssueLineApi.OutsourceIssueLine) {
- lineFormModalApi.setData({ id: row.id, issueId: props.issueId }).open();
-}
-
-/** 鍒犻櫎鐗╂枡 */
-async function handleDelete(
- row: MesWmOutsourceIssueLineApi.OutsourceIssueLine,
-) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.itemName]),
- duration: 0,
- });
- try {
- await deleteOutsourceIssueLine(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.itemName]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-/** 鎷h揣锛氱洿鎺ユ墦寮�鏄庣粏鍒涘缓琛ㄥ崟 */
-function handlePicking(row: MesWmOutsourceIssueLineApi.OutsourceIssueLine) {
- openDetailForm(row.id!, row.itemId);
-}
-
-/** 鎵撳紑鍙戞枡鏄庣粏琛ㄥ崟 */
-function openDetailForm(lineId: number, itemId?: number, detailId?: number) {
- detailFormModalApi
- .setData({ detailId, issueId: props.issueId, itemId, lineId })
- .open();
-}
-
-/** 鑾峰彇宸插睍寮�琛岀殑鍙戞枡鏄庣粏 */
-function getExpandedDetails(
- row: MesWmOutsourceIssueLineApi.OutsourceIssueLine,
-) {
- return detailMap[row.id!] || [];
-}
-
-/** 鍔犺浇鎸囧畾琛岀殑鍙戞枡鏄庣粏 */
-async function loadLineDetails(lineId: number) {
- detailMap[lineId] = await getOutsourceIssueDetailListByLineId(lineId);
-}
-
-/** 灞曞紑琛屾椂鎳掑姞杞藉彂鏂欐槑缁� */
-async function handleExpandChange(
- row: MesWmOutsourceIssueLineApi.OutsourceIssueLine,
- expanded: boolean,
-) {
- if (!expanded) {
- return;
- }
- await loadLineDetails(row.id!);
-}
-
-/** 鏄庣粏琛ㄥ崟鎻愪氦鎴愬姛鍚庯紝鍒锋柊瀵瑰簲琛屽凡灞曞紑鐨勬槑缁� */
-async function handleDetailSuccess(lineId: number) {
- await loadLineDetails(lineId);
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- gridOptions: {
- columns: useLineGridColumns(isEditable.value, isStock.value),
- expandConfig: {
- padding: true,
- },
- height: 400,
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }) => {
- if (!props.issueId) {
- return { list: [], total: 0 };
- }
- return await getOutsourceIssueLinePage({
- issueId: props.issueId,
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- },
- } as VxeTableGridOptions<MesWmOutsourceIssueLineApi.OutsourceIssueLine>,
- gridEvents: {
- toggleRowExpand: ({
- expanded,
- row,
- }: {
- expanded: boolean;
- row: MesWmOutsourceIssueLineApi.OutsourceIssueLine;
- }) => {
- handleExpandChange(row, expanded);
- },
- },
-});
-</script>
-
-<template>
- <div>
- <LineFormModal @success="handleRefresh" />
- <DetailFormModal @success="handleDetailSuccess" />
- <Grid table-title="鐗╂枡淇℃伅">
- <template v-if="isEditable" #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: '娣诲姞鐗╂枡',
- type: 'primary',
- icon: ACTION_ICON.ADD,
- onClick: handleCreate,
- },
- ]"
- />
- </template>
- <template #detail="{ row }">
- <DetailList
- :details="getExpandedDetails(row)"
- :form-type="formType"
- @edit="(detailId) => openDetailForm(row.id!, row.itemId, detailId)"
- @refresh="loadLineDetails(row.id!)"
- />
- </template>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- ifShow: isEditable,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- ifShow: isEditable,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.itemName]),
- confirm: handleDelete.bind(null, row),
- },
- },
- {
- label: '鎷h揣',
- type: 'link',
- ifShow: isStock,
- onClick: handlePicking.bind(null, row),
- },
- ]"
- />
- </template>
- </Grid>
- </div>
-</template>
diff --git a/src/views/outsourcereceipt/data.ts b/src/views/outsourcereceipt/data.ts
deleted file mode 100644
index bc03596..0000000
--- a/src/views/outsourcereceipt/data.ts
+++ /dev/null
@@ -1,540 +0,0 @@
-锘縤mport type { VbenFormApi, VbenFormSchema } from '#/adapter/form';
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesProWorkOrderApi } from '#/api/mes/pro/workorder';
-import type { MesWmOutsourceReceiptApi } from '#/api/mes/wm/outsourcereceipt';
-import type { MesWmOutsourceReceiptDetailApi } from '#/api/mes/wm/outsourcereceipt/detail';
-import type { MesWmOutsourceReceiptLineApi } from '#/api/mes/wm/outsourcereceipt/line';
-
-import { h, markRaw } from 'vue';
-
-import {
- DICT_TYPE,
- MesAutoCodeRuleCode,
- MesProWorkOrderStatusEnum,
- MesProWorkOrderTypeEnum,
-} from '@vben/constants';
-import { getDictOptions } from '@vben/hooks';
-
-import { Button } from 'ant-design-vue';
-
-import { z } from '#/adapter/form';
-import { generateAutoCode } from '#/api/mes/md/autocode/record';
-import { getRangePickerDefaultProps } from '#/utils';
-import { MdItemSelect } from '#/views/mes/md/item/components';
-import { MdVendorSelect } from '#/views/mes/md/vendor/components';
-import { ProWorkOrderSelect } from '#/views/mes/pro/workorder/components';
-import {
- WmWarehouseAreaSelect,
- WmWarehouseLocationSelect,
- WmWarehouseSelect,
-} from '#/views/wls/warehouse/components';
-
-/** 琛ㄥ崟绫诲瀷 */
-export type FormType = 'create' | 'detail' | 'finish' | 'stock' | 'update';
-
-/** 琛ㄥ崟澶撮儴鏄惁鍙锛堜笂鏋躲�佽鎯呫�佸畬鎴愭�侊級 */
-function isHeaderReadonly(formType: FormType): boolean {
- return formType === 'detail' || formType === 'finish' || formType === 'stock';
-}
-
-/** 鏂板/淇敼鐨勮〃鍗� */
-export function useFormSchema(
- formType: FormType,
- formApi?: VbenFormApi,
-): VbenFormSchema[] {
- return [
- {
- fieldName: 'id',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'status',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'code',
- label: '鍏ュ簱鍗曠紪鍙�',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ュ叆搴撳崟缂栧彿',
- },
- rules: 'required',
- suffix: isHeaderReadonly(formType)
- ? undefined
- : () =>
- h(
- Button,
- {
- type: 'default',
- onClick: async () => {
- const code = await generateAutoCode(
- MesAutoCodeRuleCode.WM_OUTSOURCE_RECEIPT_CODE,
- );
- await formApi?.setFieldValue('code', code);
- },
- },
- { default: () => '鐢熸垚' },
- ),
- },
- {
- fieldName: 'name',
- label: '鍏ュ簱鍗曞悕绉�',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ュ叆搴撳崟鍚嶇О',
- },
- rules: 'required',
- },
- {
- fieldName: 'workOrderId',
- label: '澶栧崗璁㈠崟',
- component: markRaw(ProWorkOrderSelect),
- componentProps: {
- // 閫夋嫨澶栧崗璁㈠崟鍚庯紝鑷姩鍥炲~渚涘簲鍟�
- onChange: async (workOrder?: MesProWorkOrderApi.WorkOrder) => {
- await formApi?.setFieldValue('vendorId', workOrder?.vendorId);
- },
- status: MesProWorkOrderStatusEnum.CONFIRMED,
- type: MesProWorkOrderTypeEnum.OUTSOURCE,
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'vendorId',
- label: '渚涘簲鍟�',
- component: markRaw(MdVendorSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨渚涘簲鍟�',
- },
- },
- {
- fieldName: 'receiptDate',
- label: '鍏ュ簱鏃ユ湡',
- component: 'DatePicker',
- componentProps: {
- format: 'YYYY-MM-DD',
- placeholder: '璇烽�夋嫨鍏ュ簱鏃ユ湡',
- valueFormat: 'x',
- },
- rules: 'required',
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勬悳绱㈣〃鍗� */
-export function useGridFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'code',
- label: '鍏ュ簱鍗曠紪鍙�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ュ叆搴撳崟缂栧彿',
- },
- },
- {
- fieldName: 'name',
- label: '鍏ュ簱鍗曞悕绉�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ュ叆搴撳崟鍚嶇О',
- },
- },
- {
- fieldName: 'workOrderCode',
- label: '澶栧崗璁㈠崟鍙�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ュ鍗忚鍗曞彿',
- },
- },
- {
- fieldName: 'vendorId',
- label: '渚涘簲鍟�',
- component: markRaw(MdVendorSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨渚涘簲鍟�',
- },
- },
- {
- fieldName: 'status',
- label: '鐘舵��',
- component: 'Select',
- componentProps: {
- allowClear: true,
- options: getDictOptions(
- DICT_TYPE.MES_WM_OUTSOURCE_RECEIPT_STATUS,
- 'number',
- ),
- placeholder: '璇烽�夋嫨鍗曟嵁鐘舵��',
- },
- },
- {
- fieldName: 'receiptDate',
- label: '鍏ュ簱鏃ユ湡',
- component: 'RangePicker',
- componentProps: {
- ...getRangePickerDefaultProps(),
- allowClear: true,
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勫瓧娈� */
-export function useGridColumns(): VxeTableGridOptions<MesWmOutsourceReceiptApi.OutsourceReceipt>['columns'] {
- return [
- {
- field: 'code',
- title: '鍏ュ簱鍗曠紪鍙�',
- minWidth: 160,
- slots: { default: 'code' },
- },
- {
- field: 'name',
- title: '鍏ュ簱鍗曞悕绉�',
- minWidth: 150,
- },
- {
- field: 'workOrderCode',
- title: '澶栧崗璁㈠崟鍙�',
- minWidth: 140,
- },
- {
- field: 'vendorName',
- title: '渚涘簲鍟嗗悕绉�',
- minWidth: 120,
- },
- {
- field: 'receiptDate',
- title: '鍏ュ簱鏃ユ湡',
- width: 180,
- formatter: 'formatDate',
- },
- {
- field: 'status',
- title: '鍗曟嵁鐘舵��',
- minWidth: 100,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_OUTSOURCE_RECEIPT_STATUS },
- },
- },
- {
- title: '鎿嶄綔',
- width: 240,
- fixed: 'right',
- slots: { default: 'actions' },
- },
- ];
-}
-
-/** 鍏ュ簱鍗曡瀛愯〃鐨勫瓧娈� */
-export function useLineGridColumns(
- editable: boolean,
- stockable: boolean,
-): VxeTableGridOptions<MesWmOutsourceReceiptLineApi.OutsourceReceiptLine>['columns'] {
- return [
- {
- type: 'expand',
- width: 48,
- slots: { content: 'detail' },
- },
- {
- field: 'itemCode',
- title: '鐗╂枡缂栫爜',
- minWidth: 120,
- },
- {
- field: 'itemName',
- title: '鐗╂枡鍚嶇О',
- minWidth: 140,
- },
- {
- field: 'specification',
- title: '瑙勬牸鍨嬪彿',
- minWidth: 120,
- },
- {
- field: 'unitMeasureName',
- title: '鍗曚綅',
- width: 80,
- },
- {
- field: 'quantity',
- title: '鍏ュ簱鏁伴噺',
- width: 100,
- },
- {
- field: 'batchCode',
- title: '鎵规鍙�',
- minWidth: 120,
- },
- {
- field: 'iqcCheckFlag',
- title: '鏄惁妫�楠�',
- width: 100,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.INFRA_BOOLEAN_STRING },
- },
- },
- {
- field: 'qualityStatus',
- title: '璐ㄩ噺鐘舵��',
- minWidth: 100,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_QUALITY_STATUS },
- },
- },
- ...(editable || stockable
- ? [
- {
- title: '鎿嶄綔',
- width: 180,
- fixed: 'right',
- slots: { default: 'actions' },
- } as const,
- ]
- : []),
- ];
-}
-
-/** 鍏ュ簱鍗曡鏂板/淇敼鐨勮〃鍗� */
-export function useLineFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'itemId',
- label: '鐗╂枡',
- component: markRaw(MdItemSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨鐗╂枡',
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'quantity',
- label: '鍏ュ簱鏁伴噺',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0,
- placeholder: '璇疯緭鍏ュ叆搴撴暟閲�',
- precision: 2,
- },
- rules: 'required',
- },
- {
- fieldName: 'batchCode',
- label: '鎵规鍙�',
- component: 'Input',
- componentProps: {
- disabled: true,
- placeholder: '绯荤粺鑷姩鐢熸垚',
- },
- },
- {
- fieldName: 'productionDate',
- label: '鐢熶骇鏃ユ湡',
- component: 'DatePicker',
- componentProps: {
- class: '!w-full',
- format: 'YYYY-MM-DD',
- placeholder: '璇烽�夋嫨鐢熶骇鏃ユ湡',
- valueFormat: 'x',
- },
- },
- {
- fieldName: 'expireDate',
- label: '鏈夋晥鏈�',
- component: 'DatePicker',
- componentProps: {
- class: '!w-full',
- format: 'YYYY-MM-DD',
- placeholder: '璇烽�夋嫨鏈夋晥鏈�',
- valueFormat: 'x',
- },
- },
- {
- fieldName: 'lotNumber',
- label: '鎵瑰彿',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ユ壒鍙�',
- },
- },
- {
- fieldName: 'iqcCheckFlag',
- label: '鏄惁璐ㄦ',
- component: 'Switch',
- rules: z.boolean().default(false),
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
-
-/** 鍏ュ簱鏄庣粏瀛愯〃鐨勫瓧娈� */
-export function useDetailGridColumns(
- editable: boolean,
-): VxeTableGridOptions<MesWmOutsourceReceiptDetailApi.OutsourceReceiptDetail>['columns'] {
- return [
- {
- field: 'warehouseName',
- title: '浠撳簱鍚嶇О',
- minWidth: 100,
- },
- {
- field: 'locationName',
- title: '搴撳尯鍚嶇О',
- minWidth: 100,
- },
- {
- field: 'areaName',
- title: '搴撲綅鍚嶇О',
- minWidth: 100,
- },
- {
- field: 'quantity',
- title: '鏁伴噺',
- width: 100,
- },
- ...(editable
- ? [
- {
- title: '鎿嶄綔',
- width: 120,
- fixed: 'right',
- slots: { default: 'actions' },
- } as const,
- ]
- : []),
- ];
-}
-
-/** 鍏ュ簱鏄庣粏鏂板/淇敼鐨勮〃鍗� */
-export function useDetailFormSchema(formApi?: VbenFormApi): VbenFormSchema[] {
- return [
- {
- fieldName: 'itemId',
- label: '鐗╂枡',
- component: markRaw(MdItemSelect),
- componentProps: {
- disabled: true,
- },
- },
- {
- fieldName: 'batchCode',
- label: '鎵规鍙�',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ユ壒娆″彿',
- },
- rules: 'required',
- },
- {
- fieldName: 'warehouseId',
- label: '鍏ュ簱浠撳簱',
- component: markRaw(WmWarehouseSelect),
- componentProps: {
- // 鍒囨崲浠撳簱鍚庢竻绌哄簱鍖哄拰搴撲綅
- onChange: async () => {
- await formApi?.setValues({
- areaId: undefined,
- locationId: undefined,
- });
- },
- placeholder: '璇烽�夋嫨浠撳簱',
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'locationId',
- label: '搴撳尯',
- component: markRaw(WmWarehouseLocationSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨搴撳尯',
- },
- rules: 'selectRequired',
- dependencies: {
- triggerFields: ['warehouseId'],
- componentProps: (values) => ({
- // 鍒囨崲搴撳尯鍚庢竻绌哄簱浣�
- onChange: async () => {
- await formApi?.setFieldValue('areaId', undefined);
- },
- placeholder: '璇烽�夋嫨搴撳尯',
- warehouseId: values.warehouseId,
- }),
- },
- },
- {
- fieldName: 'areaId',
- label: '搴撲綅',
- component: markRaw(WmWarehouseAreaSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨搴撲綅',
- },
- rules: 'selectRequired',
- dependencies: {
- triggerFields: ['locationId'],
- componentProps: (values) => ({
- locationId: values.locationId,
- placeholder: '璇烽�夋嫨搴撲綅',
- }),
- },
- },
- {
- fieldName: 'quantity',
- label: '鏁伴噺',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0,
- placeholder: '璇疯緭鍏ユ暟閲�',
- precision: 2,
- },
- rules: 'required',
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-2',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
diff --git a/src/views/outsourcereceipt/index.vue b/src/views/outsourcereceipt/index.vue
deleted file mode 100644
index 2de48d9..0000000
--- a/src/views/outsourcereceipt/index.vue
+++ /dev/null
@@ -1,201 +0,0 @@
-<script lang="ts" setup>
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmOutsourceReceiptApi } from '#/api/mes/wm/outsourcereceipt';
-
-import { Page, useVbenModal } from '@vben/common-ui';
-import { MesWmOutsourceReceiptStatusEnum } from '@vben/constants';
-import { downloadFileFromBlobPart } from '@vben/utils';
-
-import { Button, message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import {
- cancelOutsourceReceipt,
- deleteOutsourceReceipt,
- exportOutsourceReceipt,
- getOutsourceReceiptPage,
-} from '#/api/mes/wm/outsourcereceipt';
-import { $t } from '#/locales';
-
-import { useGridColumns, useGridFormSchema } from './data';
-import Form from './modules/form.vue';
-
-const [FormModal, formModalApi] = useVbenModal({
- connectedComponent: Form,
- destroyOnClose: true,
-});
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- gridApi.query();
-}
-
-/** 鍒涘缓澶栧崗鍏ュ簱鍗� */
-function handleCreate() {
- formModalApi.setData({ formType: 'create' }).open();
-}
-
-/** 鏌ョ湅澶栧崗鍏ュ簱鍗� */
-function handleDetail(row: MesWmOutsourceReceiptApi.OutsourceReceipt) {
- formModalApi.setData({ formType: 'detail', id: row.id }).open();
-}
-
-/** 缂栬緫澶栧崗鍏ュ簱鍗� */
-function handleEdit(row: MesWmOutsourceReceiptApi.OutsourceReceipt) {
- formModalApi.setData({ formType: 'update', id: row.id }).open();
-}
-
-/** 鎵ц涓婃灦 */
-function handleStock(row: MesWmOutsourceReceiptApi.OutsourceReceipt) {
- formModalApi.setData({ formType: 'stock', id: row.id }).open();
-}
-
-/** 瀹屾垚鍏ュ簱 */
-function handleFinish(row: MesWmOutsourceReceiptApi.OutsourceReceipt) {
- formModalApi.setData({ formType: 'finish', id: row.id }).open();
-}
-
-/** 鍒犻櫎澶栧崗鍏ュ簱鍗� */
-async function handleDelete(row: MesWmOutsourceReceiptApi.OutsourceReceipt) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.code]),
- duration: 0,
- });
- try {
- await deleteOutsourceReceipt(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.code]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-/** 鍙栨秷澶栧崗鍏ュ簱鍗� */
-async function handleCancel(row: MesWmOutsourceReceiptApi.OutsourceReceipt) {
- await cancelOutsourceReceipt(row.id!);
- message.success('鍙栨秷鎴愬姛');
- handleRefresh();
-}
-
-/** 瀵煎嚭琛ㄦ牸 */
-async function handleExport() {
- const data = await exportOutsourceReceipt(await gridApi.formApi.getValues());
- downloadFileFromBlobPart({ fileName: '澶栧崗鍏ュ簱鍗�.xls', source: data });
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- formOptions: {
- schema: useGridFormSchema(),
- },
- gridOptions: {
- columns: useGridColumns(),
- height: 'auto',
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }, formValues) => {
- return await getOutsourceReceiptPage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- ...formValues,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- search: true,
- },
- } as VxeTableGridOptions<MesWmOutsourceReceiptApi.OutsourceReceipt>,
-});
-</script>
-
-<template>
- <Page auto-content-height><FormModal @success="handleRefresh" />
-
- <Grid table-title="澶栧崗鍏ュ簱鍗曞垪琛�">
- <template #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: $t('ui.actionTitle.create', ['澶栧崗鍏ュ簱鍗�']),
- type: 'primary',
- icon: ACTION_ICON.ADD,
- auth: ['mes:wm-outsource-receipt:create'],
- onClick: handleCreate,
- },
- {
- label: $t('ui.actionTitle.export'),
- type: 'primary',
- icon: ACTION_ICON.DOWNLOAD,
- auth: ['mes:wm-outsource-receipt:export'],
- onClick: handleExport,
- },
- ]"
- />
- </template>
- <template #code="{ row }">
- <Button type="link" @click="handleDetail(row)">
- {{ row.code }}
- </Button>
- </template>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- auth: ['mes:wm-outsource-receipt:update'],
- ifShow: row.status === MesWmOutsourceReceiptStatusEnum.PREPARE,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- auth: ['mes:wm-outsource-receipt:delete'],
- ifShow: row.status === MesWmOutsourceReceiptStatusEnum.PREPARE,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.code]),
- confirm: handleDelete.bind(null, row),
- },
- },
- {
- label: '鎵ц涓婃灦',
- type: 'link',
- auth: ['mes:wm-outsource-receipt:update'],
- ifShow: row.status === MesWmOutsourceReceiptStatusEnum.APPROVING,
- onClick: handleStock.bind(null, row),
- },
- {
- label: '瀹屾垚鍏ュ簱',
- type: 'link',
- auth: ['mes:wm-outsource-receipt:finish'],
- ifShow: row.status === MesWmOutsourceReceiptStatusEnum.APPROVED,
- onClick: handleFinish.bind(null, row),
- },
- {
- label: '鍙栨秷',
- type: 'link',
- danger: true,
- auth: ['mes:wm-outsource-receipt:update'],
- ifShow:
- row.status === MesWmOutsourceReceiptStatusEnum.APPROVING ||
- row.status === MesWmOutsourceReceiptStatusEnum.APPROVED,
- popConfirm: {
- title: '纭鍙栨秷璇ュ鍗忓叆搴撳崟锛熷彇娑堝悗涓嶅彲鎭㈠銆�',
- confirm: handleCancel.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </Page>
-</template>
diff --git a/src/views/outsourcereceipt/modules/detail-form.vue b/src/views/outsourcereceipt/modules/detail-form.vue
deleted file mode 100644
index 7501857..0000000
--- a/src/views/outsourcereceipt/modules/detail-form.vue
+++ /dev/null
@@ -1,103 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmOutsourceReceiptDetailApi } from '#/api/mes/wm/outsourcereceipt/detail';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createOutsourceReceiptDetail,
- getOutsourceReceiptDetail,
- updateOutsourceReceiptDetail,
-} from '#/api/mes/wm/outsourcereceipt/detail';
-import { $t } from '#/locales';
-
-import { useDetailFormSchema } from '../data';
-
-const emit = defineEmits<{ success: [lineId: number] }>();
-const formData = ref<MesWmOutsourceReceiptDetailApi.OutsourceReceiptDetail>();
-const receiptId = ref<number>(); // 鎵�灞炲叆搴撳崟缂栧彿
-const lineId = ref<number>(); // 鎵�灞炲叆搴撳崟琛岀紪鍙�
-const getTitle = computed(() => {
- return formData.value?.id
- ? $t('ui.actionTitle.edit', ['鏀惰揣鏄庣粏'])
- : $t('ui.actionTitle.create', ['鏀惰揣鏄庣粏']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 90,
- },
- layout: 'horizontal',
- schema: useDetailFormSchema(),
- showDefaultActions: false,
- wrapperClass: 'grid-cols-2',
-});
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data =
- (await formApi.getValues()) as MesWmOutsourceReceiptDetailApi.OutsourceReceiptDetail;
- data.receiptId = receiptId.value;
- data.lineId = lineId.value;
- try {
- await (formData.value?.id
- ? updateOutsourceReceiptDetail({ ...data, id: formData.value.id })
- : createOutsourceReceiptDetail(data));
- // 鍏抽棴骞舵彁绀�
- await modalApi.close();
- emit('success', lineId.value!);
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- return;
- }
- formApi.setState({ schema: useDetailFormSchema(formApi) });
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{
- detailId?: number;
- itemId?: number;
- lineId: number;
- receiptId: number;
- }>();
- receiptId.value = data.receiptId;
- lineId.value = data.lineId;
- if (data.detailId) {
- modalApi.lock();
- try {
- formData.value = await getOutsourceReceiptDetail(data.detailId);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- } else if (data.itemId) {
- await formApi.setFieldValue('itemId', data.itemId);
- }
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-1/2">
- <Form class="mx-4" />
- </Modal>
-</template>
diff --git a/src/views/outsourcereceipt/modules/detail-list.vue b/src/views/outsourcereceipt/modules/detail-list.vue
deleted file mode 100644
index adf8ce2..0000000
--- a/src/views/outsourcereceipt/modules/detail-list.vue
+++ /dev/null
@@ -1,127 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmOutsourceReceiptDetailApi } from '#/api/mes/wm/outsourcereceipt/detail';
-
-import { computed, watch } from 'vue';
-
-import { message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import { deleteOutsourceReceiptDetail } from '#/api/mes/wm/outsourcereceipt/detail';
-import { $t } from '#/locales';
-
-import { useDetailGridColumns } from '../data';
-
-const props = defineProps<{
- details: MesWmOutsourceReceiptDetailApi.OutsourceReceiptDetail[];
- formType: FormType;
-}>();
-
-const emit = defineEmits<{
- edit: [detailId?: number];
- refresh: [];
-}>();
-
-const isEditable = computed(() =>
- // 鏄惁鍙淮鎶ゆ敹璐ф槑缁嗭紙缂栬緫鎴栦笂鏋舵�侊級
- ['create', 'stock', 'update'].includes(props.formType),
-);
-
-/** 娣诲姞鏀惰揣鏄庣粏 */
-function handleCreate() {
- emit('edit', undefined);
-}
-
-/** 缂栬緫鏀惰揣鏄庣粏 */
-function handleEdit(
- row: MesWmOutsourceReceiptDetailApi.OutsourceReceiptDetail,
-) {
- emit('edit', row.id!);
-}
-
-/** 鍒犻櫎鏀惰揣鏄庣粏 */
-async function handleDelete(
- row: MesWmOutsourceReceiptDetailApi.OutsourceReceiptDetail,
-) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.warehouseName]),
- duration: 0,
- });
- try {
- await deleteOutsourceReceiptDetail(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.warehouseName]));
- emit('refresh');
- } finally {
- hideLoading();
- }
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- gridOptions: {
- border: true,
- columns: useDetailGridColumns(isEditable.value),
- data: props.details,
- pagerConfig: {
- enabled: false,
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- size: 'small',
- toolbarConfig: {
- enabled: false,
- },
- } as VxeTableGridOptions<MesWmOutsourceReceiptDetailApi.OutsourceReceiptDetail>,
-});
-
-watch(
- () => props.details,
- (details) => gridApi.setGridOptions({ data: details }),
-);
-</script>
-
-<template>
- <div class="px-4 py-2">
- <TableAction
- v-if="isEditable"
- class="mb-2"
- :actions="[
- {
- label: '娣诲姞鏄庣粏',
- type: 'primary',
- icon: ACTION_ICON.ADD,
- onClick: handleCreate,
- },
- ]"
- />
- <Grid>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [
- row.warehouseName,
- ]),
- confirm: handleDelete.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </div>
-</template>
diff --git a/src/views/outsourcereceipt/modules/form.vue b/src/views/outsourcereceipt/modules/form.vue
deleted file mode 100644
index db74d57..0000000
--- a/src/views/outsourcereceipt/modules/form.vue
+++ /dev/null
@@ -1,227 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { MesWmOutsourceReceiptApi } from '#/api/mes/wm/outsourcereceipt';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-import { MesWmOutsourceReceiptStatusEnum } from '@vben/constants';
-
-import { Button, Divider, message, Popconfirm } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createOutsourceReceipt,
- finishOutsourceReceipt,
- getOutsourceReceipt,
- stockOutsourceReceipt,
- submitOutsourceReceipt,
- updateOutsourceReceipt,
-} from '#/api/mes/wm/outsourcereceipt';
-import { $t } from '#/locales';
-
-import { useFormSchema } from '../data';
-import LineList from './line-list.vue';
-
-const emit = defineEmits(['success']);
-const formType = ref<FormType>('create');
-const formData = ref<MesWmOutsourceReceiptApi.OutsourceReceipt>();
-const originalSnapshot = ref(''); // 琛ㄥ崟鍘熷鏁版嵁蹇収锛岀敤浜庢彁浜ゆ椂璺宠繃鏈彉鏇寸殑淇濆瓨璇锋眰
-const isEditable = computed(() =>
- // 鏄惁涓虹紪杈戞ā寮忥紙鍙繚瀛橈級
- ['create', 'update'].includes(formType.value),
-);
-const isStock = computed(() => formType.value === 'stock'); // 鏄惁涓轰笂鏋舵ā寮�
-const isFinish = computed(() => formType.value === 'finish'); // 鏄惁涓哄畬鎴愬叆搴撴ā寮�
-const canSubmit = computed(
- () =>
- // 鏄惁鍙彁浜�
- formType.value === 'update' &&
- formData.value?.status === MesWmOutsourceReceiptStatusEnum.PREPARE,
-);
-const getTitle = computed(() => {
- if (formType.value === 'detail') {
- return $t('ui.actionTitle.view', ['澶栧崗鍏ュ簱鍗�']);
- }
- if (formType.value === 'stock') {
- return '鎵ц涓婃灦';
- }
- if (formType.value === 'finish') {
- return '瀹屾垚鍏ュ簱';
- }
- return formType.value === 'update'
- ? $t('ui.actionTitle.edit', ['澶栧崗鍏ュ簱鍗�'])
- : $t('ui.actionTitle.create', ['澶栧崗鍏ュ簱鍗�']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 110,
- },
- layout: 'horizontal',
- schema: [],
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-/** 鎻愪氦鍏ュ簱鍗曪細琛ㄥ崟鏈変慨鏀规椂鍏堜繚瀛橈紝鍐嶈皟鐢ㄦ彁浜ゆ帴鍙� */
-async function handleSubmit() {
- const { valid } = await formApi.validate();
- if (!valid || !formData.value?.id) {
- return;
- }
- modalApi.lock();
- try {
- const current = JSON.stringify(await formApi.getValues());
- if (current !== originalSnapshot.value) {
- const data =
- (await formApi.getValues()) as MesWmOutsourceReceiptApi.OutsourceReceipt;
- await updateOutsourceReceipt({ ...formData.value, ...data });
- originalSnapshot.value = current;
- }
- await submitOutsourceReceipt(formData.value.id);
- message.success('鎻愪氦鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-/** 鎵ц涓婃灦 */
-async function handleStock() {
- if (!formData.value?.id) {
- return;
- }
- modalApi.lock();
- try {
- await stockOutsourceReceipt(formData.value.id);
- message.success('涓婃灦鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-/** 瀹屾垚鍏ュ簱 */
-async function handleFinish() {
- if (!formData.value?.id) {
- return;
- }
- modalApi.lock();
- try {
- await finishOutsourceReceipt(formData.value.id);
- message.success('鍏ュ簱鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- if (!isEditable.value) {
- await modalApi.close();
- return;
- }
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data =
- (await formApi.getValues()) as MesWmOutsourceReceiptApi.OutsourceReceipt;
- try {
- if (formData.value?.id) {
- await updateOutsourceReceipt({ ...formData.value, ...data });
- formData.value = { ...formData.value, ...data };
- } else {
- const id = await createOutsourceReceipt(data);
- formData.value = {
- ...data,
- id,
- status: MesWmOutsourceReceiptStatusEnum.PREPARE,
- };
- await formApi.setFieldValue('id', id);
- await formApi.setFieldValue('status', formData.value.status);
- formType.value = 'update';
- }
- originalSnapshot.value = JSON.stringify(await formApi.getValues());
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- originalSnapshot.value = '';
- return;
- }
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{ formType: FormType; id?: number }>();
- formType.value = data.formType;
- formApi.setState({ schema: useFormSchema(formType.value, formApi) });
- formApi.setDisabled(!isEditable.value);
- modalApi.setState({ showConfirmButton: isEditable.value });
- if (data?.id) {
- modalApi.lock();
- try {
- formData.value = await getOutsourceReceipt(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- }
- originalSnapshot.value = JSON.stringify(await formApi.getValues());
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- <!-- 闈炴柊寤烘ā寮忓睍绀虹墿鏂欎俊鎭� -->
- <template v-if="formData?.id">
- <Divider>鐗╂枡淇℃伅</Divider>
- <div class="mx-4">
- <LineList :form-type="formType" :receipt-id="formData.id" />
- </div>
- </template>
- <template #prepend-footer>
- <div class="flex flex-auto items-center gap-2">
- <Popconfirm
- v-if="canSubmit"
- title="纭鎻愪氦璇ュ鍗忓叆搴撳崟锛熴�愭彁浜ゅ悗灏嗕笉鑳戒慨鏀广��"
- @confirm="handleSubmit"
- >
- <Button type="primary">鎻愪氦</Button>
- </Popconfirm>
- <Popconfirm
- v-if="isStock"
- title="纭鎵ц涓婃灦锛�"
- @confirm="handleStock"
- >
- <Button type="primary">鎵ц涓婃灦</Button>
- </Popconfirm>
- <Popconfirm
- v-if="isFinish"
- title="纭瀹屾垚鍏ュ簱锛熷畬鎴愬悗灏嗘洿鏂板簱瀛樺彴璐︺��"
- @confirm="handleFinish"
- >
- <Button type="primary">瀹屾垚鍏ュ簱</Button>
- </Popconfirm>
- </div>
- </template>
- </Modal>
-</template>
diff --git a/src/views/outsourcereceipt/modules/line-form.vue b/src/views/outsourcereceipt/modules/line-form.vue
deleted file mode 100644
index f0a612c..0000000
--- a/src/views/outsourcereceipt/modules/line-form.vue
+++ /dev/null
@@ -1,98 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmOutsourceReceiptLineApi } from '#/api/mes/wm/outsourcereceipt/line';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createOutsourceReceiptLine,
- getOutsourceReceiptLine,
- updateOutsourceReceiptLine,
-} from '#/api/mes/wm/outsourcereceipt/line';
-import { $t } from '#/locales';
-
-import { useLineFormSchema } from '../data';
-
-const emit = defineEmits(['success']);
-const formData = ref<MesWmOutsourceReceiptLineApi.OutsourceReceiptLine>();
-const receiptId = ref<number>(); // 鎵�灞炲叆搴撳崟缂栧彿
-
-const getTitle = computed(() => {
- return formData.value?.id
- ? $t('ui.actionTitle.edit', ['澶栧崗鍏ュ簱鍗曡'])
- : $t('ui.actionTitle.create', ['澶栧崗鍏ュ簱鍗曡']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 90,
- },
- layout: 'horizontal',
- schema: useLineFormSchema(),
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟锛堟壒娆″彿鐢卞悗绔嚜鍔ㄧ敓鎴愶紝涓嶆彁浜わ級
- const data =
- (await formApi.getValues()) as MesWmOutsourceReceiptLineApi.OutsourceReceiptLine;
- data.receiptId = receiptId.value;
- delete data.batchCode;
- try {
- await (formData.value?.id
- ? updateOutsourceReceiptLine({ ...data, id: formData.value.id })
- : createOutsourceReceiptLine(data));
- // 鍏抽棴骞舵彁绀�
- await modalApi.close();
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- return;
- }
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{
- id?: number;
- receiptId: number;
- }>();
- receiptId.value = data.receiptId;
- if (!data.id) {
- return;
- }
- modalApi.lock();
- try {
- formData.value = await getOutsourceReceiptLine(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- </Modal>
-</template>
diff --git a/src/views/outsourcereceipt/modules/line-list.vue b/src/views/outsourcereceipt/modules/line-list.vue
deleted file mode 100644
index 1dcf161..0000000
--- a/src/views/outsourcereceipt/modules/line-list.vue
+++ /dev/null
@@ -1,236 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmOutsourceReceiptDetailApi } from '#/api/mes/wm/outsourcereceipt/detail';
-import type { MesWmOutsourceReceiptLineApi } from '#/api/mes/wm/outsourcereceipt/line';
-
-import { computed, reactive } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import { getOutsourceReceiptDetailListByLineId } from '#/api/mes/wm/outsourcereceipt/detail';
-import {
- deleteOutsourceReceiptLine,
- getOutsourceReceiptLinePage,
-} from '#/api/mes/wm/outsourcereceipt/line';
-import { $t } from '#/locales';
-import { PrinterLabel } from '#/views/wls/barcode/components';
-
-import { useLineGridColumns } from '../data';
-import DetailForm from './detail-form.vue';
-import DetailList from './detail-list.vue';
-import LineForm from './line-form.vue';
-
-const props = defineProps<{
- formType: FormType;
- receiptId: number;
-}>();
-
-const isEditable = computed(() =>
- // 鏄惁鍙紪杈戞槑缁嗚
- ['create', 'update'].includes(props.formType),
-);
-const isStock = computed(() => props.formType === 'stock'); // 鏄惁涓轰笂鏋舵ā寮�
-const detailMap = reactive<
- Record<number, MesWmOutsourceReceiptDetailApi.OutsourceReceiptDetail[]>
->({}); // 宸插睍寮�琛岀殑鏀惰揣鏄庣粏缂撳瓨
-
-const [LineFormModal, lineFormModalApi] = useVbenModal({
- connectedComponent: LineForm,
- destroyOnClose: true,
-});
-
-const [DetailFormModal, detailFormModalApi] = useVbenModal({
- connectedComponent: DetailForm,
- destroyOnClose: true,
-});
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- for (const id of Object.keys(detailMap)) {
- delete detailMap[Number(id)];
- }
- gridApi.query();
-}
-
-/** 娣诲姞鐗╂枡 */
-function handleCreate() {
- lineFormModalApi.setData({ receiptId: props.receiptId }).open();
-}
-
-/** 缂栬緫鐗╂枡 */
-function handleEdit(row: MesWmOutsourceReceiptLineApi.OutsourceReceiptLine) {
- lineFormModalApi.setData({ id: row.id, receiptId: props.receiptId }).open();
-}
-
-/** 鍒犻櫎鐗╂枡 */
-async function handleDelete(
- row: MesWmOutsourceReceiptLineApi.OutsourceReceiptLine,
-) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.itemName]),
- duration: 0,
- });
- try {
- await deleteOutsourceReceiptLine(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.itemName]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-/** 涓婃灦锛氱洿鎺ユ墦寮�鏄庣粏鍒涘缓琛ㄥ崟 */
-function handlePicking(row: MesWmOutsourceReceiptLineApi.OutsourceReceiptLine) {
- openDetailForm(row.id!, row.itemId);
-}
-
-/** 鎵撳紑鏀惰揣鏄庣粏琛ㄥ崟 */
-function openDetailForm(lineId: number, itemId?: number, detailId?: number) {
- detailFormModalApi
- .setData({ detailId, itemId, lineId, receiptId: props.receiptId })
- .open();
-}
-
-/** 鑾峰彇宸插睍寮�琛岀殑鏀惰揣鏄庣粏 */
-function getExpandedDetails(
- row: MesWmOutsourceReceiptLineApi.OutsourceReceiptLine,
-) {
- return detailMap[row.id!] || [];
-}
-
-/** 鍔犺浇鎸囧畾琛岀殑鏀惰揣鏄庣粏 */
-async function loadLineDetails(lineId: number) {
- detailMap[lineId] = await getOutsourceReceiptDetailListByLineId(lineId);
-}
-
-/** 灞曞紑琛屾椂鎳掑姞杞芥敹璐ф槑缁� */
-async function handleExpandChange(
- row: MesWmOutsourceReceiptLineApi.OutsourceReceiptLine,
- expanded: boolean,
-) {
- if (!expanded) {
- return;
- }
- await loadLineDetails(row.id!);
-}
-
-/** 鏄庣粏琛ㄥ崟鎻愪氦鎴愬姛鍚庯紝鍒锋柊瀵瑰簲琛屽凡灞曞紑鐨勬槑缁� */
-async function handleDetailSuccess(lineId: number) {
- await loadLineDetails(lineId);
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- gridOptions: {
- columns: useLineGridColumns(isEditable.value, isStock.value),
- expandConfig: {
- padding: true,
- },
- height: 400,
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }) => {
- if (!props.receiptId) {
- return { list: [], total: 0 };
- }
- return await getOutsourceReceiptLinePage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- receiptId: props.receiptId,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- },
- } as VxeTableGridOptions<MesWmOutsourceReceiptLineApi.OutsourceReceiptLine>,
- gridEvents: {
- toggleRowExpand: ({
- expanded,
- row,
- }: {
- expanded: boolean;
- row: MesWmOutsourceReceiptLineApi.OutsourceReceiptLine;
- }) => {
- handleExpandChange(row, expanded);
- },
- },
-});
-</script>
-
-<template>
- <div>
- <LineFormModal @success="handleRefresh" />
- <DetailFormModal @success="handleDetailSuccess" />
- <Grid table-title="鐗╂枡淇℃伅">
- <template v-if="isEditable" #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: '娣诲姞鐗╂枡',
- type: 'primary',
- icon: ACTION_ICON.ADD,
- onClick: handleCreate,
- },
- ]"
- />
- </template>
- <template #detail="{ row }">
- <DetailList
- :details="getExpandedDetails(row)"
- :form-type="formType"
- @edit="(detailId) => openDetailForm(row.id!, row.itemId, detailId)"
- @refresh="loadLineDetails(row.id!)"
- />
- </template>
- <template #actions="{ row }">
- <div class="flex items-center justify-center">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- ifShow: isEditable,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- ifShow: isEditable,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.itemName]),
- confirm: handleDelete.bind(null, row),
- },
- },
- {
- label: '涓婃灦',
- type: 'link',
- ifShow: isStock,
- onClick: handlePicking.bind(null, row),
- },
- ]"
- />
- <PrinterLabel
- v-if="isStock"
- :biz-code="row.batchCode"
- :biz-id="row.batchId"
- biz-type="BATCH"
- />
- </div>
- </template>
- </Grid>
- </div>
-</template>
diff --git a/src/views/packages/components/index.ts b/src/views/packages/components/index.ts
deleted file mode 100644
index de95a06..0000000
--- a/src/views/packages/components/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export { default as WmPackageSelectDialog } from './select-dialog.vue';
-export { default as WmPackageSelect } from './select.vue';
diff --git a/src/views/packages/components/select-dialog.vue b/src/views/packages/components/select-dialog.vue
deleted file mode 100644
index 9190be3..0000000
--- a/src/views/packages/components/select-dialog.vue
+++ /dev/null
@@ -1,231 +0,0 @@
-<script lang="ts" setup>
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmPackageApi } from '#/api/mes/wm/packages';
-
-import { nextTick, ref } from 'vue';
-
-import { MesWmPackageStatusEnum } from '@vben/constants';
-
-import { Alert, Button, message, Modal } from 'ant-design-vue';
-
-import { useVbenVxeGrid } from '#/adapter/vxe-table';
-import { getPackagePage } from '#/api/mes/wm/packages';
-
-import { useSelectGridColumns, useSelectGridFormSchema } from '../data';
-
-const props = withDefaults(
- defineProps<{
- childableOnly?: boolean; // 鍙睍绀哄彲浣滀负瀛愮鐨勮绠卞崟锛堟棤鐖剁 + 宸插畬鎴愮姸鎬侊級
- excludeId?: number; // 鎺掗櫎鐨勭紪鍙凤紙閬垮厤閫夋嫨鑷繁浣滀负鐖剁锛�
- }>(),
- {
- childableOnly: false,
- excludeId: undefined,
- },
-);
-
-const emit = defineEmits<{
- selected: [rows: MesWmPackageApi.Package[]];
-}>();
-
-const open = ref(false); // 寮圭獥鏄惁鎵撳紑
-const multiple = ref(true); // 鏄惁澶氶��
-const selectedRows = ref<MesWmPackageApi.Package[]>([]); // 宸查�夎绠卞崟
-const preSelectedIds = ref<number[]>([]); // 棰勯�夎绠卞崟缂栧彿
-
-/** 鑾峰彇澶氶�夎褰曪紝鍖呭惈 VXE reserve 璺ㄩ〉璁板綍 */
-function getMultipleSelectedRows() {
- const selectedMap = new Map<number, MesWmPackageApi.Package>();
- const records = [
- ...(gridApi.grid.getCheckboxReserveRecords?.() ?? []),
- ...(gridApi.grid.getCheckboxRecords?.() ?? []),
- ] as MesWmPackageApi.Package[];
- records.forEach((row) => {
- if (row.id !== undefined && row.id !== null) {
- selectedMap.set(row.id, row);
- }
- });
- return [...selectedMap.values()];
-}
-
-/** 澶勭悊鍕鹃�夊彉鍖� */
-function handleCheckboxSelectChange() {
- selectedRows.value = getMultipleSelectedRows();
-}
-
-/** 澶勭悊鍗曢�夊彉鍖� */
-function handleRadioChange(row: MesWmPackageApi.Package) {
- selectedRows.value = [row];
-}
-
-/** 澶氶�夋ā寮忎笅鍒囨崲琛屽嬀閫� */
-async function toggleMultipleRow(row: MesWmPackageApi.Package) {
- const selected = gridApi.grid.isCheckedByCheckboxRow(row);
- await gridApi.grid.setCheckboxRow(row, !selected);
- selectedRows.value = getMultipleSelectedRows();
-}
-
-/** 澶勭悊琛屽弻鍑伙細鍗曢�夌洿鎺ョ‘璁わ紱澶氶�夊垏鎹㈠嬀閫� */
-async function handleCellDblclick({ row }: { row: MesWmPackageApi.Package }) {
- if (multiple.value) {
- await toggleMultipleRow(row);
- return;
- }
- selectedRows.value = [row];
- await gridApi.grid.setRadioRow(row);
- handleConfirm();
-}
-
-/** 鍥炴樉棰勯�夎绠卞崟 */
-async function applyPreSelection() {
- if (preSelectedIds.value.length === 0) {
- return;
- }
- const rows = gridApi.grid.getData() as MesWmPackageApi.Package[];
- for (const row of rows) {
- if (
- row.id === undefined ||
- row.id === null ||
- !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();
- }
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- formOptions: {
- schema: useSelectGridFormSchema(),
- },
- gridOptions: {
- columns: useSelectGridColumns(true),
- height: 480,
- keepSource: true,
- checkboxConfig: {
- highlight: true,
- range: true,
- reserve: true,
- },
- radioConfig: {
- highlight: true,
- trigger: 'row',
- },
- proxyConfig: {
- ajax: {
- query: async ({ page }, formValues) => {
- const data = await getPackagePage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- ...formValues,
- // childableOnly 妯″紡锛氬浐瀹氳繃婊ゆ棤鐖剁 + 宸插畬鎴愮姸鎬�
- parentId: props.childableOnly ? 0 : undefined,
- status: props.childableOnly
- ? MesWmPackageStatusEnum.FINISHED
- : undefined,
- });
- // 鎺掗櫎鎸囧畾缂栧彿锛岄伩鍏嶉�夋嫨鑷繁浣滀负鐖剁
- const list = props.excludeId
- ? (data.list || []).filter((item) => item.id !== props.excludeId)
- : data.list || [];
- return { list, total: data.total };
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- search: true,
- },
- } as VxeTableGridOptions<MesWmPackageApi.Package>,
- gridEvents: {
- cellDblclick: handleCellDblclick,
- checkboxAll: handleCheckboxSelectChange,
- checkboxChange: handleCheckboxSelectChange,
- radioChange: ({ row }: { row: MesWmPackageApi.Package }) => {
- handleRadioChange(row);
- },
- },
-});
-
-/** 閲嶇疆鏌ヨ鍜岄�夋嫨鐘舵�� */
-async function resetQueryState() {
- selectedRows.value = [];
- await gridApi.grid.clearCheckboxRow();
- await gridApi.grid.clearCheckboxReserve();
- await gridApi.grid.clearRadioRow();
- await gridApi.formApi.resetForm();
-}
-
-/** 鎵撳紑瑁呯鍗曢�夋嫨寮圭獥 */
-async function openModal(
- selectedIds?: number[],
- options?: { multiple?: boolean },
-) {
- open.value = true;
- multiple.value = options?.multiple ?? true;
- preSelectedIds.value = selectedIds || [];
- await nextTick();
- gridApi.setGridOptions({
- columns: useSelectGridColumns(multiple.value),
- });
- await resetQueryState();
- await gridApi.query();
- await nextTick();
- await applyPreSelection();
-}
-
-/** 鍏抽棴寮圭獥 */
-function closeModal() {
- open.value = false;
-}
-
-/** 纭閫夋嫨 */
-function handleConfirm() {
- const rows = multiple.value ? getMultipleSelectedRows() : selectedRows.value;
- if (rows.length === 0) {
- message.warning(multiple.value ? '璇疯嚦灏戦�夋嫨涓�鏉℃暟鎹�' : '璇烽�夋嫨涓�鏉℃暟鎹�');
- return;
- }
- emit('selected', multiple.value ? rows : [rows[0]!]);
- open.value = false;
-}
-
-defineExpose({ open: openModal });
-</script>
-
-<template>
- <Modal
- v-model:open="open"
- :destroy-on-close="true"
- title="瑁呯鍗曢�夋嫨"
- width="80%"
- @cancel="closeModal"
- @ok="handleConfirm"
- >
- <Alert
- v-if="childableOnly"
- class="mb-3"
- message="浠呭睍绀哄彲浣滀负瀛愮鐨勮绠卞崟锛堟棤鐖剁 + 宸插畬鎴愶級"
- show-icon
- type="info"
- />
- <Grid table-title="瑁呯鍗曞垪琛�" />
- <template #footer>
- <Button @click="closeModal">鍙栨秷</Button>
- <Button type="primary" @click="handleConfirm">纭畾</Button>
- </template>
- </Modal>
-</template>
diff --git a/src/views/packages/components/select.vue b/src/views/packages/components/select.vue
deleted file mode 100644
index d4dfcbb..0000000
--- a/src/views/packages/components/select.vue
+++ /dev/null
@@ -1,143 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmPackageApi } from '#/api/mes/wm/packages';
-
-import { computed, ref, useAttrs, watch } from 'vue';
-
-import { IconifyIcon } from '@vben/icons';
-
-import { Input, Tooltip } from 'ant-design-vue';
-
-import { getPackage } from '#/api/mes/wm/packages';
-
-import WmPackageSelectDialog from './select-dialog.vue';
-
-defineOptions({ name: 'WmPackageSelect', inheritAttrs: false });
-
-const props = withDefaults(
- defineProps<{
- allowClear?: boolean;
- childableOnly?: boolean; // 鍙睍绀哄彲浣滀负瀛愮鐨勮绠卞崟锛堟棤鐖剁 + 宸插畬鎴愮姸鎬侊級
- disabled?: boolean;
- excludeId?: number; // 鎺掗櫎鐨勭紪鍙凤紙閬垮厤閫夋嫨鑷繁浣滀负鐖剁锛�
- modelValue?: number;
- placeholder?: string;
- }>(),
- {
- allowClear: true,
- childableOnly: false,
- disabled: false,
- excludeId: undefined,
- modelValue: undefined,
- placeholder: '璇烽�夋嫨瑁呯鍗�',
- },
-);
-
-const emit = defineEmits<{
- change: [item: MesWmPackageApi.Package | undefined];
- 'update:modelValue': [value: number | undefined];
-}>();
-
-const attrs = useAttrs();
-const dialogRef = ref<InstanceType<typeof WmPackageSelectDialog>>();
-const hovering = ref(false);
-const selectedItem = ref<MesWmPackageApi.Package>();
-
-const displayLabel = computed(() => selectedItem.value?.code ?? '');
-
-const showClear = computed(
- () =>
- props.allowClear &&
- !props.disabled &&
- hovering.value &&
- props.modelValue !== null,
-);
-
-/** 鏍规嵁缂栧彿鍗曟潯鏌ヨ瑁呯鍗曚俊鎭紙鐢ㄤ簬缂栬緫鍥炴樉锛� */
-async function resolveItemById(id: number | undefined) {
- if (!id) {
- selectedItem.value = undefined;
- return;
- }
- if (selectedItem.value?.id === id) {
- return;
- }
- selectedItem.value = await getPackage(id);
-}
-
-watch(() => props.modelValue, resolveItemById, { 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]
- ) as number[];
- dialogRef.value?.open(selectedIds, { multiple: false });
-}
-
-/** 寮圭獥閫変腑鍥炶皟 */
-function handleSelected(rows: MesWmPackageApi.Package[]) {
- const item = rows[0];
- if (!item) {
- return;
- }
- selectedItem.value = item;
- emit('update:modelValue', item.id);
- emit('change', item);
-}
-</script>
-
-<template>
- <div
- v-bind="attrs"
- class="w-full"
- :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.clientName || '-' }}</div>
- <div>閿�鍞鍗曪細{{ selectedItem.salesOrderCode || '-' }}</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>
- <WmPackageSelectDialog
- ref="dialogRef"
- :childable-only="childableOnly"
- :exclude-id="excludeId"
- @selected="handleSelected"
- />
-</template>
diff --git a/src/views/packages/data.ts b/src/views/packages/data.ts
deleted file mode 100644
index 3c0b502..0000000
--- a/src/views/packages/data.ts
+++ /dev/null
@@ -1,641 +0,0 @@
-锘縤mport type { VbenFormApi, VbenFormSchema } from '#/adapter/form';
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmPackageApi } from '#/api/mes/wm/packages';
-import type { MesWmPackageLineApi } from '#/api/mes/wm/packages/line';
-
-import { h, markRaw } from 'vue';
-
-import {
- DICT_TYPE,
- MesAutoCodeRuleCode,
- MesProWorkOrderStatusEnum,
-} from '@vben/constants';
-
-import { Button } from 'ant-design-vue';
-
-import { generateAutoCode } from '#/api/mes/md/autocode/record';
-import { getSimpleUserList } from '#/api/system/user';
-import { MdClientSelect } from '#/views/mes/md/client/components';
-import { MdItemSelect } from '#/views/mes/md/item/components';
-import { MdUnitMeasureSelect } from '#/views/mes/md/unitmeasure/components';
-import { ProWorkOrderSelect } from '#/views/mes/pro/workorder/components';
-
-/** 琛ㄥ崟绫诲瀷 */
-export type FormType = 'create' | 'detail' | 'update';
-
-/** 鏂板/淇敼鐨勮〃鍗� */
-export function useFormSchema(
- formType: FormType,
- formApi?: VbenFormApi,
-): VbenFormSchema[] {
- return [
- {
- fieldName: 'id',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'status',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'code',
- label: '瑁呯鍗曠紪鍙�',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ヨ绠卞崟缂栧彿',
- },
- rules: 'required',
- suffix:
- formType === 'detail'
- ? undefined
- : () =>
- h(
- Button,
- {
- type: 'default',
- onClick: async () => {
- const code = await generateAutoCode(
- MesAutoCodeRuleCode.WM_PACKAGE_CODE,
- );
- await formApi?.setFieldValue('code', code);
- },
- },
- { default: () => '鐢熸垚' },
- ),
- },
- {
- fieldName: 'packageDate',
- label: '瑁呯鏃ユ湡',
- component: 'DatePicker',
- componentProps: {
- format: 'YYYY-MM-DD',
- placeholder: '璇烽�夋嫨瑁呯鏃ユ湡',
- valueFormat: 'x',
- },
- rules: 'required',
- },
- {
- fieldName: 'inspectorUserId',
- label: '妫�鏌ュ憳',
- component: 'ApiSelect',
- componentProps: {
- allowClear: true,
- api: getSimpleUserList,
- labelField: 'nickname',
- placeholder: '璇烽�夋嫨妫�鏌ュ憳',
- valueField: 'id',
- },
- },
- {
- fieldName: 'salesOrderCode',
- label: '閿�鍞鍗曠紪鍙�',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ラ攢鍞鍗曠紪鍙�',
- },
- },
- {
- fieldName: 'invoiceCode',
- label: '鍙戠エ缂栧彿',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ュ彂绁ㄧ紪鍙�',
- },
- },
- {
- fieldName: 'clientId',
- label: '瀹㈡埛',
- component: markRaw(MdClientSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨瀹㈡埛',
- },
- },
- {
- fieldName: 'sizeUnitId',
- label: '灏哄鍗曚綅',
- component: markRaw(MdUnitMeasureSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨灏哄鍗曚綅',
- },
- },
- {
- fieldName: 'length',
- label: '绠遍暱搴�',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0,
- placeholder: '璇疯緭鍏ョ闀垮害',
- precision: 2,
- },
- },
- {
- fieldName: 'width',
- label: '绠卞搴�',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0,
- placeholder: '璇疯緭鍏ョ瀹藉害',
- precision: 2,
- },
- },
- {
- fieldName: 'height',
- label: '绠遍珮搴�',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0,
- placeholder: '璇疯緭鍏ョ楂樺害',
- precision: 2,
- },
- },
- {
- fieldName: 'weightUnitId',
- label: '閲嶉噺鍗曚綅',
- component: markRaw(MdUnitMeasureSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨閲嶉噺鍗曚綅',
- },
- },
- {
- fieldName: 'netWeight',
- label: '鍑�閲�',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0,
- placeholder: '璇疯緭鍏ュ噣閲�',
- precision: 2,
- },
- },
- {
- fieldName: 'grossWeight',
- label: '姣涢噸',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0,
- placeholder: '璇疯緭鍏ユ瘺閲�',
- precision: 2,
- },
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勬悳绱㈣〃鍗� */
-export function useGridFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'code',
- label: '瑁呯鍗曠紪鍙�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ヨ绠卞崟缂栧彿',
- },
- },
- {
- fieldName: 'salesOrderCode',
- label: '閿�鍞鍗曠紪鍙�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ラ攢鍞鍗曠紪鍙�',
- },
- },
- {
- fieldName: 'clientId',
- label: '瀹㈡埛',
- component: markRaw(MdClientSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨瀹㈡埛',
- },
- },
- {
- fieldName: 'inspectorUserId',
- label: '妫�鏌ュ憳',
- component: 'ApiSelect',
- componentProps: {
- allowClear: true,
- api: getSimpleUserList,
- labelField: 'nickname',
- placeholder: '璇烽�夋嫨妫�鏌ュ憳',
- valueField: 'id',
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勫瓧娈� */
-export function useGridColumns(): VxeTableGridOptions<MesWmPackageApi.Package>['columns'] {
- return [
- {
- field: 'code',
- title: '瑁呯鍗曠紪鍙�',
- minWidth: 250,
- fixed: 'left',
- treeNode: true,
- slots: { default: 'code' },
- },
- {
- field: 'packageDate',
- title: '瑁呯鏃ユ湡',
- width: 120,
- formatter: 'formatDate',
- },
- {
- field: 'salesOrderCode',
- title: '閿�鍞鍗曠紪鍙�',
- minWidth: 140,
- },
- {
- field: 'invoiceCode',
- title: '鍙戠エ缂栧彿',
- minWidth: 120,
- },
- {
- field: 'clientCode',
- title: '瀹㈡埛缂栫爜',
- minWidth: 100,
- },
- {
- field: 'clientName',
- title: '瀹㈡埛鍚嶇О',
- minWidth: 120,
- },
- {
- field: 'length',
- title: '绠遍暱搴�',
- width: 80,
- },
- {
- field: 'width',
- title: '绠卞搴�',
- width: 80,
- },
- {
- field: 'height',
- title: '绠遍珮搴�',
- width: 80,
- },
- {
- field: 'sizeUnitName',
- title: '灏哄鍗曚綅',
- width: 90,
- },
- {
- field: 'netWeight',
- title: '鍑�閲�',
- width: 80,
- },
- {
- field: 'grossWeight',
- title: '姣涢噸',
- width: 80,
- },
- {
- field: 'weightUnitName',
- title: '閲嶉噺鍗曚綅',
- width: 90,
- },
- {
- field: 'inspectorName',
- title: '妫�鏌ュ憳',
- minWidth: 100,
- },
- {
- field: 'status',
- title: '鍗曟嵁鐘舵��',
- minWidth: 100,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_PACKAGE_STATUS },
- },
- },
- {
- title: '鎿嶄綔',
- width: 160,
- fixed: 'right',
- slots: { default: 'actions' },
- },
- ];
-}
-
-/** 瀛愮鍒楄〃鐨勫瓧娈� */
-export function useSubPackageGridColumns(): VxeTableGridOptions<MesWmPackageApi.Package>['columns'] {
- return [
- {
- field: 'code',
- title: '瑁呯鍗曠紪鍙�',
- minWidth: 160,
- fixed: 'left',
- },
- {
- field: 'packageDate',
- title: '瑁呯鏃ユ湡',
- width: 120,
- formatter: 'formatDate',
- },
- {
- field: 'salesOrderCode',
- title: '閿�鍞鍗曠紪鍙�',
- minWidth: 140,
- },
- {
- field: 'invoiceCode',
- title: '鍙戠エ缂栧彿',
- minWidth: 120,
- },
- {
- field: 'clientCode',
- title: '瀹㈡埛缂栫爜',
- minWidth: 100,
- },
- {
- field: 'clientName',
- title: '瀹㈡埛鍚嶇О',
- minWidth: 120,
- },
- {
- field: 'netWeight',
- title: '鍑�閲�',
- width: 80,
- },
- {
- field: 'grossWeight',
- title: '姣涢噸',
- width: 80,
- },
- {
- field: 'weightUnitName',
- title: '閲嶉噺鍗曚綅',
- width: 90,
- },
- {
- field: 'inspectorName',
- title: '妫�鏌ュ憳',
- minWidth: 100,
- },
- {
- field: 'status',
- title: '鍗曟嵁鐘舵��',
- minWidth: 100,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_PACKAGE_STATUS },
- },
- },
- {
- title: '鎿嶄綔',
- width: 100,
- fixed: 'right',
- slots: { default: 'actions' },
- },
- ];
-}
-
-/** 瑁呯鏄庣粏鐨勮〃鍗� */
-export function useLineFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'workOrderId',
- label: '鐢熶骇璁㈠崟',
- component: markRaw(ProWorkOrderSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨鐢熶骇璁㈠崟',
- status: MesProWorkOrderStatusEnum.CONFIRMED,
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'itemId',
- label: '浜у搧鐗╂枡',
- component: markRaw(MdItemSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨浜у搧鐗╂枡',
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'quantity',
- label: '瑁呯鏁伴噺',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0.01,
- placeholder: '璇疯緭鍏ヨ绠辨暟閲�',
- precision: 2,
- },
- rules: 'required',
- },
- {
- fieldName: 'expireDate',
- label: '鏈夋晥鏈�',
- component: 'DatePicker',
- componentProps: {
- format: 'YYYY-MM-DD',
- placeholder: '璇烽�夋嫨鏈夋晥鏈�',
- valueFormat: 'x',
- },
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-2',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
-
-/** 瑁呯鏄庣粏鍒楄〃鐨勫瓧娈� */
-export function useLineGridColumns(): VxeTableGridOptions<MesWmPackageLineApi.PackageLine>['columns'] {
- return [
- {
- field: 'itemCode',
- title: '浜у搧鐗╂枡缂栫爜',
- minWidth: 120,
- },
- {
- field: 'itemName',
- title: '浜у搧鐗╂枡鍚嶇О',
- minWidth: 140,
- },
- {
- field: 'specification',
- title: '瑙勬牸鍨嬪彿',
- minWidth: 120,
- },
- {
- field: 'unitMeasureName',
- title: '鍗曚綅',
- width: 80,
- },
- {
- field: 'quantity',
- title: '瑁呯鏁伴噺',
- width: 100,
- },
- {
- field: 'workOrderCode',
- title: '鐢熶骇璁㈠崟缂栧彿',
- minWidth: 140,
- },
- {
- field: 'batchCode',
- title: '鎵规鍙�',
- minWidth: 120,
- },
- {
- field: 'expireDate',
- title: '鏈夋晥鏈�',
- width: 120,
- formatter: 'formatDate',
- },
- {
- title: '鎿嶄綔',
- width: 120,
- fixed: 'right',
- slots: { default: 'actions' },
- },
- ];
-}
-
-/** 閫夋嫨寮圭獥鐨勬悳绱㈣〃鍗� */
-export function useSelectGridFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'code',
- label: '瑁呯鍗曠紪鍙�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ヨ绠卞崟缂栧彿',
- },
- },
- {
- fieldName: 'salesOrderCode',
- label: '閿�鍞鍗曠紪鍙�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ラ攢鍞鍗曠紪鍙�',
- },
- },
- {
- fieldName: 'clientId',
- label: '瀹㈡埛',
- component: markRaw(MdClientSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨瀹㈡埛',
- },
- },
- {
- fieldName: 'inspectorUserId',
- label: '妫�鏌ュ憳',
- component: 'ApiSelect',
- componentProps: {
- allowClear: true,
- api: getSimpleUserList,
- labelField: 'nickname',
- placeholder: '璇烽�夋嫨妫�鏌ュ憳',
- valueField: 'id',
- },
- },
- ];
-}
-
-/** 閫夋嫨寮圭獥鐨勫瓧娈� */
-export function useSelectGridColumns(
- multiple = true,
-): VxeTableGridOptions<MesWmPackageApi.Package>['columns'] {
- return [
- {
- type: multiple ? 'checkbox' : 'radio',
- width: 50,
- },
- {
- field: 'code',
- title: '瑁呯鍗曠紪鍙�',
- minWidth: 160,
- },
- {
- field: 'packageDate',
- title: '瑁呯鏃ユ湡',
- width: 120,
- formatter: 'formatDate',
- },
- {
- field: 'salesOrderCode',
- title: '閿�鍞鍗曠紪鍙�',
- minWidth: 140,
- },
- {
- field: 'invoiceCode',
- title: '鍙戠エ缂栧彿',
- minWidth: 120,
- },
- {
- field: 'clientCode',
- title: '瀹㈡埛缂栫爜',
- minWidth: 100,
- },
- {
- field: 'clientName',
- title: '瀹㈡埛鍚嶇О',
- minWidth: 120,
- },
- {
- field: 'netWeight',
- title: '鍑�閲�',
- width: 80,
- },
- {
- field: 'grossWeight',
- title: '姣涢噸',
- width: 80,
- },
- {
- field: 'weightUnitName',
- title: '閲嶉噺鍗曚綅',
- width: 90,
- },
- {
- field: 'inspectorName',
- title: '妫�鏌ュ憳',
- minWidth: 100,
- },
- {
- field: 'status',
- title: '鍗曟嵁鐘舵��',
- minWidth: 100,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_PACKAGE_STATUS },
- },
- },
- ];
-}
diff --git a/src/views/packages/index.vue b/src/views/packages/index.vue
deleted file mode 100644
index 6996fa8..0000000
--- a/src/views/packages/index.vue
+++ /dev/null
@@ -1,160 +0,0 @@
-<script lang="ts" setup>
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmPackageApi } from '#/api/mes/wm/packages';
-
-import { ref } from 'vue';
-
-import { Page, useVbenModal } from '@vben/common-ui';
-import { MesWmPackageStatusEnum } from '@vben/constants';
-
-import { Button, message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import { deletePackage, getPackagePage } from '#/api/mes/wm/packages';
-import { $t } from '#/locales';
-
-import { useGridColumns, useGridFormSchema } from './data';
-import Form from './modules/form.vue';
-
-const [FormModal, formModalApi] = useVbenModal({
- connectedComponent: Form,
- destroyOnClose: true,
-});
-
-const isExpanded = ref(true); // 鏍戝舰琛ㄦ牸鏄惁灞曞紑
-
-/** 鍒囨崲鏍戝舰灞曞紑/鏀剁缉鐘舵�� */
-function handleExpand() {
- isExpanded.value = !isExpanded.value;
- gridApi.grid.setAllTreeExpand(isExpanded.value);
-}
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- gridApi.query();
-}
-
-/** 鍒涘缓瑁呯鍗� */
-function handleCreate() {
- formModalApi.setData({ formType: 'create' }).open();
-}
-
-/** 鏌ョ湅瑁呯鍗� */
-function handleDetail(row: MesWmPackageApi.Package) {
- formModalApi.setData({ formType: 'detail', id: row.id }).open();
-}
-
-/** 缂栬緫瑁呯鍗� */
-function handleEdit(row: MesWmPackageApi.Package) {
- formModalApi.setData({ formType: 'update', id: row.id }).open();
-}
-
-/** 鍒犻櫎瑁呯鍗� */
-async function handleDelete(row: MesWmPackageApi.Package) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.code]),
- duration: 0,
- });
- try {
- await deletePackage(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.code]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- formOptions: {
- schema: useGridFormSchema(),
- },
- gridOptions: {
- columns: useGridColumns(),
- height: 'auto',
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }, formValues) => {
- return await getPackagePage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- ...formValues,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- search: true,
- },
- treeConfig: {
- parentField: 'parentId',
- rowField: 'id',
- transform: true,
- expandAll: true,
- reserve: true,
- },
- } as VxeTableGridOptions<MesWmPackageApi.Package>,
-});
-</script>
-
-<template>
- <Page auto-content-height><FormModal @success="handleRefresh" />
-
- <Grid table-title="瑁呯鍗曞垪琛�">
- <template #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: $t('ui.actionTitle.create', ['瑁呯鍗�']),
- type: 'primary',
- icon: ACTION_ICON.ADD,
- auth: ['mes:wm-package:create'],
- onClick: handleCreate,
- },
- {
- label: isExpanded ? '鏀剁缉' : '灞曞紑',
- type: 'primary',
- onClick: handleExpand,
- },
- ]"
- />
- </template>
- <template #code="{ row }">
- <Button type="link" @click="handleDetail(row)">
- {{ row.code }}
- </Button>
- </template>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- auth: ['mes:wm-package:update'],
- ifShow: row.status === MesWmPackageStatusEnum.PREPARE,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- auth: ['mes:wm-package:delete'],
- ifShow: row.status === MesWmPackageStatusEnum.PREPARE,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.code]),
- confirm: handleDelete.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </Page>
-</template>
diff --git a/src/views/packages/modules/form.vue b/src/views/packages/modules/form.vue
deleted file mode 100644
index d81813f..0000000
--- a/src/views/packages/modules/form.vue
+++ /dev/null
@@ -1,193 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { MesWmPackageApi } from '#/api/mes/wm/packages';
-
-import { computed, ref } from 'vue';
-
-import { confirm, useVbenModal } from '@vben/common-ui';
-import { MesWmPackageStatusEnum } from '@vben/constants';
-
-import { Button, message, Tabs } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createPackage,
- finishPackage,
- getPackage,
- updatePackage,
-} from '#/api/mes/wm/packages';
-import { $t } from '#/locales';
-
-import { useFormSchema } from '../data';
-import PackageLineList from './package-line-list.vue';
-import SubPackageList from './sub-package-list.vue';
-
-const emit = defineEmits(['success']);
-const formType = ref<FormType>('create');
-const formData = ref<MesWmPackageApi.Package>();
-const subTabsName = ref('subPackage'); // 瀛愯〃褰撳墠 tab
-const originalSnapshot = ref(''); // 琛ㄥ崟鍘熷鏁版嵁蹇収锛岀敤浜� finish 鏃惰烦杩囨湭鍙樻洿鐨勪繚瀛樿姹�
-
-const isEditable = computed(() =>
- ['create', 'update'].includes(formType.value),
-);
-const canFinish = computed(
- () =>
- formType.value === 'update' &&
- formData.value?.status === MesWmPackageStatusEnum.PREPARE,
-);
-const getTitle = computed(() => {
- if (formType.value === 'detail') {
- return $t('ui.actionTitle.view', ['瑁呯鍗�']);
- }
- return formType.value === 'update'
- ? $t('ui.actionTitle.edit', ['瑁呯鍗�'])
- : $t('ui.actionTitle.create', ['瑁呯鍗�']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 110,
- },
- layout: 'horizontal',
- schema: [],
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-/** 鎻愪氦琛ㄥ崟锛坈reate/update锛夛紝鏂板鎴愬姛鍚庡垏鎹负缂栬緫鎬佷互缁х画缁存姢瀛愯〃 */
-async function handleSubmit(): Promise<boolean> {
- const { valid } = await formApi.validate();
- if (!valid) {
- return false;
- }
- const data = (await formApi.getValues()) as MesWmPackageApi.Package;
- if (formData.value?.id) {
- await updatePackage({ ...data, id: formData.value.id });
- formData.value = { ...formData.value, ...data };
- } else {
- const id = await createPackage(data);
- formData.value = {
- ...data,
- id,
- status: MesWmPackageStatusEnum.PREPARE,
- };
- await formApi.setFieldValue('id', id);
- await formApi.setFieldValue('status', MesWmPackageStatusEnum.PREPARE);
- formType.value = 'update';
- }
- // 鍒锋柊蹇収锛屼笅娆� finish 鐢ㄤ簬鍒ゆ柇鏄惁闇�瑕佸啀淇濆瓨
- originalSnapshot.value = JSON.stringify(await formApi.getValues());
- return true;
-}
-
-/** 瀹屾垚瑁呯鍗曪細缂栬緫鎬佹湁淇敼鏃跺厛淇濆瓨锛屽啀璋冪敤瀹屾垚鎺ュ彛 */
-async function handleFinish() {
- const id = formData.value?.id;
- if (!id) {
- return;
- }
- try {
- await confirm('纭瀹屾垚璇ヨ绠卞崟锛熷畬鎴愬悗灏嗕笉鍙紪杈戙��');
- } catch {
- return;
- }
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- try {
- const current = JSON.stringify(await formApi.getValues());
- if (current !== originalSnapshot.value) {
- const data = (await formApi.getValues()) as MesWmPackageApi.Package;
- await updatePackage({ ...data, id });
- originalSnapshot.value = current;
- }
- await finishPackage(id);
- message.success('瀹屾垚鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- if (formType.value === 'detail') {
- await modalApi.close();
- return;
- }
- modalApi.lock();
- try {
- // 鎻愪氦琛ㄥ崟
- const ok = await handleSubmit();
- if (!ok) {
- return;
- }
- // 鍏抽棴骞舵彁绀�
- message.success($t('ui.actionMessage.operationSuccess'));
- emit('success');
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- originalSnapshot.value = '';
- return;
- }
- subTabsName.value = 'subPackage';
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{ formType: FormType; id?: number }>();
- formType.value = data.formType;
- formApi.setState({ schema: useFormSchema(formType.value, formApi) });
- formApi.setDisabled(formType.value === 'detail');
- modalApi.setState({ showConfirmButton: formType.value !== 'detail' });
- if (data?.id) {
- modalApi.lock();
- try {
- formData.value = await getPackage(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- }
- // 璁板綍鍒濆蹇収锛屽悗缁� finish 鐢ㄤ簬鍒ゆ柇鏄惁闇�瑕佸啀淇濆瓨
- originalSnapshot.value = JSON.stringify(await formApi.getValues());
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-4/5">
- <Form class="mx-4" />
- <Tabs
- v-if="formData?.id"
- v-model:active-key="subTabsName"
- class="mx-4 mt-4"
- >
- <Tabs.TabPane key="subPackage" tab="瀛愮">
- <SubPackageList :editable="isEditable" :package-id="formData.id" />
- </Tabs.TabPane>
- <Tabs.TabPane key="packageLine" tab="瑁呯娓呭崟">
- <PackageLineList :editable="isEditable" :package-id="formData.id" />
- </Tabs.TabPane>
- </Tabs>
- <template #prepend-footer>
- <div class="flex flex-auto items-center gap-2">
- <Button v-if="canFinish" type="primary" @click="handleFinish">
- 瀹屾垚
- </Button>
- </div>
- </template>
- </Modal>
-</template>
diff --git a/src/views/packages/modules/line-form.vue b/src/views/packages/modules/line-form.vue
deleted file mode 100644
index 93539ff..0000000
--- a/src/views/packages/modules/line-form.vue
+++ /dev/null
@@ -1,92 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmPackageLineApi } from '#/api/mes/wm/packages/line';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createPackageLine,
- getPackageLine,
- updatePackageLine,
-} from '#/api/mes/wm/packages/line';
-import { $t } from '#/locales';
-
-import { useLineFormSchema } from '../data';
-
-const emit = defineEmits(['success']);
-const formData = ref<MesWmPackageLineApi.PackageLine>();
-const packageId = ref<number>(); // 鎵�灞炶绠卞崟缂栧彿
-const getTitle = computed(() =>
- formData.value?.id
- ? $t('ui.actionTitle.edit', ['瑁呯鏄庣粏'])
- : $t('ui.actionTitle.create', ['瑁呯鏄庣粏']),
-);
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 100,
- },
- layout: 'horizontal',
- schema: useLineFormSchema(),
- showDefaultActions: false,
- wrapperClass: 'grid-cols-2',
-});
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data = (await formApi.getValues()) as MesWmPackageLineApi.PackageLine;
- data.packageId = packageId.value;
- try {
- await (formData.value?.id
- ? updatePackageLine({ ...data, id: formData.value.id })
- : createPackageLine(data));
- // 鍏抽棴骞舵彁绀�
- await modalApi.close();
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- return;
- }
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{ id?: number; packageId: number }>();
- packageId.value = data.packageId;
- if (!data.id) {
- return;
- }
- modalApi.lock();
- try {
- formData.value = await getPackageLine(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-2/5">
- <Form />
- </Modal>
-</template>
diff --git a/src/views/packages/modules/package-line-list.vue b/src/views/packages/modules/package-line-list.vue
deleted file mode 100644
index 14be505..0000000
--- a/src/views/packages/modules/package-line-list.vue
+++ /dev/null
@@ -1,132 +0,0 @@
-<script lang="ts" setup>
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmPackageLineApi } from '#/api/mes/wm/packages/line';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import {
- deletePackageLine,
- getPackageLinePage,
-} from '#/api/mes/wm/packages/line';
-import { $t } from '#/locales';
-
-import { useLineGridColumns } from '../data';
-import LineForm from './line-form.vue';
-
-const props = defineProps<{
- editable: boolean; // 鏄惁鍙紪杈戯紙鑽夌鎬侊級
- packageId: number; // 鎵�灞炶绠卞崟缂栧彿
-}>();
-
-const [LineFormModal, lineFormModalApi] = useVbenModal({
- connectedComponent: LineForm,
- destroyOnClose: true,
-});
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- gridApi.query();
-}
-
-/** 娣诲姞瑁呯鏄庣粏 */
-function handleCreate() {
- lineFormModalApi.setData({ packageId: props.packageId }).open();
-}
-
-/** 缂栬緫瑁呯鏄庣粏 */
-function handleEdit(row: MesWmPackageLineApi.PackageLine) {
- lineFormModalApi.setData({ id: row.id, packageId: props.packageId }).open();
-}
-
-/** 鍒犻櫎瑁呯鏄庣粏 */
-async function handleDelete(row: MesWmPackageLineApi.PackageLine) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.itemName]),
- duration: 0,
- });
- try {
- await deletePackageLine(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.itemName]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- gridOptions: {
- columns: useLineGridColumns(),
- height: 360,
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }) => {
- if (!props.packageId) {
- return { list: [], total: 0 };
- }
- return await getPackageLinePage({
- packageId: props.packageId,
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- },
- } as VxeTableGridOptions<MesWmPackageLineApi.PackageLine>,
-});
-</script>
-
-<template>
- <div>
- <LineFormModal @success="handleRefresh" />
- <Grid table-title="瑁呯娓呭崟">
- <template #toolbar-tools>
- <TableAction
- v-if="editable"
- :actions="[
- {
- label: $t('ui.actionTitle.create', ['瑁呯鏄庣粏']),
- type: 'primary',
- icon: ACTION_ICON.ADD,
- onClick: handleCreate,
- },
- ]"
- />
- </template>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- ifShow: editable,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- ifShow: editable,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.itemName]),
- confirm: handleDelete.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </div>
-</template>
diff --git a/src/views/packages/modules/sub-package-list.vue b/src/views/packages/modules/sub-package-list.vue
deleted file mode 100644
index b35bc3d..0000000
--- a/src/views/packages/modules/sub-package-list.vue
+++ /dev/null
@@ -1,126 +0,0 @@
-<script lang="ts" setup>
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmPackageApi } from '#/api/mes/wm/packages';
-
-import { ref } from 'vue';
-
-import { message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import {
- addChildPackage,
- getPackagePage,
- removeChildPackage,
-} from '#/api/mes/wm/packages';
-import { $t } from '#/locales';
-
-import { WmPackageSelectDialog } from '../components';
-import { useSubPackageGridColumns } from '../data';
-
-const props = defineProps<{
- editable: boolean; // 鏄惁鍙紪杈戯紙鑽夌鎬侊級
- packageId: number; // 鐖剁缂栧彿
-}>();
-
-const dialogRef = ref<InstanceType<typeof WmPackageSelectDialog>>();
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- gridApi.query();
-}
-
-/** 鎵撳紑瑁呯鍗曢�夋嫨寮圭獥娣诲姞瀛愮 */
-function handleAddChild() {
- dialogRef.value?.open([], { multiple: false });
-}
-
-/** 閫変腑鍥炶皟锛氬皢閫変腑鐨勮绠卞崟娣诲姞涓哄瓙绠� */
-async function handleSelected(rows: MesWmPackageApi.Package[]) {
- const child = rows[0];
- if (!child?.id) {
- return;
- }
- await addChildPackage(props.packageId, child.id);
- message.success($t('ui.actionMessage.operationSuccess'));
- handleRefresh();
-}
-
-/** 绉婚櫎瀛愮锛氬皢瀛愮鐨勭埗绠辩紪鍙锋竻绌� */
-async function handleRemoveChild(row: MesWmPackageApi.Package) {
- await removeChildPackage(row.id!);
- message.success('绉婚櫎鎴愬姛');
- handleRefresh();
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- gridOptions: {
- columns: useSubPackageGridColumns(),
- height: 360,
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }) => {
- if (!props.packageId) {
- return { list: [], total: 0 };
- }
- return await getPackagePage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- parentId: props.packageId,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- },
- } as VxeTableGridOptions<MesWmPackageApi.Package>,
-});
-</script>
-
-<template>
- <div>
- <WmPackageSelectDialog
- ref="dialogRef"
- childable-only
- :exclude-id="packageId"
- @selected="handleSelected"
- />
- <Grid table-title="瀛愮鍒楄〃">
- <template #toolbar-tools>
- <TableAction
- v-if="editable"
- :actions="[
- {
- label: '娣诲姞瀛愮',
- type: 'primary',
- icon: ACTION_ICON.ADD,
- onClick: handleAddChild,
- },
- ]"
- />
- </template>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: '绉婚櫎',
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- ifShow: editable,
- popConfirm: {
- title: '纭灏嗚瑁呯鍗曚粠瀛愮鍒楄〃涓Щ闄わ紵',
- confirm: handleRemoveChild.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </div>
-</template>
diff --git a/src/views/productissue/data.ts b/src/views/productissue/data.ts
deleted file mode 100644
index 3fe3931..0000000
--- a/src/views/productissue/data.ts
+++ /dev/null
@@ -1,475 +0,0 @@
-锘縤mport type { VbenFormApi, VbenFormSchema } from '#/adapter/form';
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmMaterialStockApi } from '#/api/mes/wm/materialstock';
-import type { MesWmProductIssueApi } from '#/api/mes/wm/productissue';
-import type { MesWmProductIssueDetailApi } from '#/api/mes/wm/productissue/detail';
-import type { MesWmProductIssueLineApi } from '#/api/mes/wm/productissue/line';
-
-import { h, markRaw } from 'vue';
-
-import {
- DICT_TYPE,
- MesAutoCodeRuleCode,
- MesProWorkOrderStatusEnum,
-} from '@vben/constants';
-import { getDictOptions } from '@vben/hooks';
-
-import { Button } from 'ant-design-vue';
-
-import { generateAutoCode } from '#/api/mes/md/autocode/record';
-import { getRangePickerDefaultProps } from '#/utils';
-import { MdItemSelect } from '#/views/mes/md/item/components';
-import { MdWorkstationSelect } from '#/views/mes/md/workstation/components';
-import { ProWorkOrderSelect } from '#/views/mes/pro/workorder/components';
-import { WmMaterialStockSelect } from '#/views/wls/materialstock/components';
-import {
- WmWarehouseAreaSelect,
- WmWarehouseLocationSelect,
- WmWarehouseSelect,
-} from '#/views/wls/warehouse/components';
-
-/** 琛ㄥ崟绫诲瀷 */
-export type FormType = 'create' | 'detail' | 'finish' | 'stock' | 'update';
-
-/** 琛ㄥ崟澶撮儴鏄惁鍙锛堟嫞璐с�佽鎯呫�佸畬鎴愭�侊級 */
-function isHeaderReadonly(formType: FormType): boolean {
- return formType === 'detail' || formType === 'finish' || formType === 'stock';
-}
-
-/** 鏂板/淇敼鐨勮〃鍗� */
-export function useFormSchema(
- formType: FormType,
- formApi?: VbenFormApi,
-): VbenFormSchema[] {
- return [
- {
- fieldName: 'id',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'status',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'code',
- label: '棰嗘枡鍗曠紪鍙�',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ラ鏂欏崟缂栧彿',
- },
- rules: 'required',
- suffix: isHeaderReadonly(formType)
- ? undefined
- : () =>
- h(
- Button,
- {
- type: 'default',
- onClick: async () => {
- const code = await generateAutoCode(
- MesAutoCodeRuleCode.WM_PRODUCT_ISSUE_CODE,
- );
- await formApi?.setFieldValue('code', code);
- },
- },
- { default: () => '鐢熸垚' },
- ),
- },
- {
- fieldName: 'name',
- label: '棰嗘枡鍗曞悕绉�',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ラ鏂欏崟鍚嶇О',
- },
- rules: 'required',
- },
- {
- fieldName: 'requiredTime',
- label: '闇�姹傛椂闂�',
- component: 'DatePicker',
- componentProps: {
- class: '!w-full',
- format: 'YYYY-MM-DD HH:mm:ss',
- placeholder: '璇烽�夋嫨闇�姹傛椂闂�',
- showTime: true,
- valueFormat: 'x',
- },
- rules: 'required',
- },
- {
- fieldName: 'workOrderId',
- label: '鐢熶骇璁㈠崟',
- component: markRaw(ProWorkOrderSelect),
- componentProps: {
- status: MesProWorkOrderStatusEnum.CONFIRMED,
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'workstationId',
- label: '宸ヤ綔绔�',
- component: markRaw(MdWorkstationSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨宸ヤ綔绔�',
- },
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勬悳绱㈣〃鍗� */
-export function useGridFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'code',
- label: '棰嗘枡鍗曠紪鍙�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ラ鏂欏崟缂栧彿',
- },
- },
- {
- fieldName: 'name',
- label: '棰嗘枡鍗曞悕绉�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ラ鏂欏崟鍚嶇О',
- },
- },
- {
- fieldName: 'issueDate',
- label: '棰嗘枡鏃ユ湡',
- component: 'RangePicker',
- componentProps: {
- ...getRangePickerDefaultProps(),
- allowClear: true,
- },
- },
- {
- fieldName: 'status',
- label: '鍗曟嵁鐘舵��',
- component: 'Select',
- componentProps: {
- allowClear: true,
- options: getDictOptions(
- DICT_TYPE.MES_WM_PRODUCT_ISSUE_STATUS,
- 'number',
- ),
- placeholder: '璇烽�夋嫨鍗曟嵁鐘舵��',
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勫瓧娈� */
-export function useGridColumns(): VxeTableGridOptions<MesWmProductIssueApi.ProductIssue>['columns'] {
- return [
- {
- field: 'code',
- title: '棰嗘枡鍗曠紪鍙�',
- minWidth: 160,
- slots: { default: 'code' },
- },
- {
- field: 'name',
- title: '棰嗘枡鍗曞悕绉�',
- minWidth: 150,
- },
- {
- field: 'workOrderCode',
- title: '鐢熶骇璁㈠崟',
- minWidth: 140,
- },
- {
- field: 'workstationName',
- title: '宸ヤ綔绔�',
- minWidth: 120,
- },
- {
- field: 'requiredTime',
- title: '闇�姹傛椂闂�',
- width: 180,
- formatter: 'formatDateTime',
- },
- {
- field: 'status',
- title: '鍗曟嵁鐘舵��',
- minWidth: 110,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_PRODUCT_ISSUE_STATUS },
- },
- },
- {
- title: '鎿嶄綔',
- width: 240,
- fixed: 'right',
- slots: { default: 'actions' },
- },
- ];
-}
-
-/** 棰嗘枡鍗曡瀛愯〃鐨勫瓧娈� */
-export function useLineGridColumns(
- editable: boolean,
- stockable: boolean,
-): VxeTableGridOptions<MesWmProductIssueLineApi.ProductIssueLine>['columns'] {
- return [
- {
- type: 'expand',
- width: 48,
- slots: { content: 'detail' },
- },
- {
- field: 'itemCode',
- title: '鐗╂枡缂栫爜',
- minWidth: 120,
- },
- {
- field: 'itemName',
- title: '鐗╂枡鍚嶇О',
- minWidth: 140,
- },
- {
- field: 'specification',
- title: '瑙勬牸鍨嬪彿',
- minWidth: 120,
- },
- {
- field: 'unitMeasureName',
- title: '鍗曚綅',
- width: 80,
- },
- {
- field: 'quantity',
- title: '棰嗘枡鏁伴噺',
- width: 100,
- },
- ...(editable || stockable
- ? [
- {
- title: '鎿嶄綔',
- width: 160,
- fixed: 'right',
- slots: { default: 'actions' },
- } as const,
- ]
- : []),
- ];
-}
-
-/** 棰嗘枡鍗曡鏂板/淇敼鐨勮〃鍗� */
-export function useLineFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'itemId',
- label: '浜у搧鐗╂枡',
- component: markRaw(MdItemSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨浜у搧鐗╂枡',
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'quantity',
- label: '棰嗘枡鏁伴噺',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0,
- placeholder: '璇疯緭鍏ラ鏂欐暟閲�',
- precision: 2,
- },
- rules: 'required',
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
-
-/** 鎷h揣鏄庣粏瀛愯〃鐨勫瓧娈� */
-export function useDetailGridColumns(
- stockable: boolean,
-): VxeTableGridOptions<MesWmProductIssueDetailApi.ProductIssueDetail>['columns'] {
- return [
- {
- field: 'batchCode',
- title: '鎵规鍙�',
- minWidth: 120,
- },
- {
- field: 'warehouseName',
- title: '浠撳簱鍚嶇О',
- minWidth: 100,
- },
- {
- field: 'locationName',
- title: '搴撳尯鍚嶇О',
- minWidth: 100,
- },
- {
- field: 'areaName',
- title: '搴撲綅鍚嶇О',
- minWidth: 100,
- },
- {
- field: 'quantity',
- title: '鏁伴噺',
- width: 100,
- },
- ...(stockable
- ? [
- {
- title: '鎿嶄綔',
- width: 120,
- fixed: 'right',
- slots: { default: 'actions' },
- } as const,
- ]
- : []),
- ];
-}
-
-/** 鎷h揣鏄庣粏鏂板/淇敼鐨勮〃鍗� */
-export function useDetailFormSchema(formApi?: VbenFormApi): VbenFormSchema[] {
- return [
- {
- fieldName: 'quantityMax',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'itemId',
- label: '鐗╂枡',
- component: markRaw(MdItemSelect),
- componentProps: {
- disabled: true,
- },
- },
- {
- fieldName: 'materialStockId',
- label: '搴撳瓨璁板綍',
- component: markRaw(WmMaterialStockSelect),
- componentProps: {
- // 閫夋嫨搴撳瓨璁板綍鍚庯紝鑷姩鍥炲~浠撳簱/搴撳尯/搴撲綅/鎵规/鏁伴噺
- onChange: async (stock?: MesWmMaterialStockApi.MaterialStock) => {
- await formApi?.setValues({
- areaId: stock?.areaId,
- batchCode: stock?.batchCode,
- batchId: stock?.batchId,
- locationId: stock?.locationId,
- quantity: stock?.quantity,
- quantityMax: stock?.quantity,
- warehouseId: stock?.warehouseId,
- });
- },
- },
- rules: 'selectRequired',
- dependencies: {
- triggerFields: ['itemId'],
- componentProps: (values) => ({
- itemId: values.itemId,
- }),
- },
- },
- {
- fieldName: 'quantity',
- label: '鏁伴噺',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0,
- placeholder: '璇疯緭鍏ユ暟閲�',
- precision: 2,
- },
- rules: 'required',
- dependencies: {
- triggerFields: ['quantityMax'],
- componentProps: (values) => ({
- class: '!w-full',
- max: values.quantityMax,
- min: 0,
- placeholder: '璇疯緭鍏ユ暟閲�',
- precision: 2,
- }),
- },
- },
- {
- fieldName: 'warehouseId',
- label: '鍑哄簱浠撳簱',
- component: markRaw(WmWarehouseSelect),
- componentProps: {
- disabled: true,
- },
- },
- {
- fieldName: 'locationId',
- label: '搴撳尯',
- component: markRaw(WmWarehouseLocationSelect),
- componentProps: {
- disabled: true,
- },
- dependencies: {
- triggerFields: ['warehouseId'],
- componentProps: (values) => ({
- disabled: true,
- warehouseId: values.warehouseId,
- }),
- },
- },
- {
- fieldName: 'areaId',
- label: '搴撲綅',
- component: markRaw(WmWarehouseAreaSelect),
- componentProps: {
- disabled: true,
- },
- dependencies: {
- triggerFields: ['locationId'],
- componentProps: (values) => ({
- disabled: true,
- locationId: values.locationId,
- }),
- },
- },
- {
- fieldName: 'batchCode',
- label: '鎵规鍙�',
- component: 'Input',
- componentProps: {
- disabled: true,
- },
- },
- ];
-}
diff --git a/src/views/productissue/index.vue b/src/views/productissue/index.vue
deleted file mode 100644
index c8a038e..0000000
--- a/src/views/productissue/index.vue
+++ /dev/null
@@ -1,219 +0,0 @@
-<script lang="ts" setup>
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmProductIssueApi } from '#/api/mes/wm/productissue';
-
-import { Page, useVbenModal } from '@vben/common-ui';
-import { MesWmProductIssueStatusEnum } from '@vben/constants';
-import { downloadFileFromBlobPart } from '@vben/utils';
-
-import { Button, message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import {
- cancelProductIssue,
- deleteProductIssue,
- exportProductIssue,
- getProductIssuePage,
- submitProductIssue,
-} from '#/api/mes/wm/productissue';
-import { $t } from '#/locales';
-
-import { useGridColumns, useGridFormSchema } from './data';
-import Form from './modules/form.vue';
-
-const [FormModal, formModalApi] = useVbenModal({
- connectedComponent: Form,
- destroyOnClose: true,
-});
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- gridApi.query();
-}
-
-/** 鍒涘缓棰嗘枡鍑哄簱鍗� */
-function handleCreate() {
- formModalApi.setData({ formType: 'create' }).open();
-}
-
-/** 鏌ョ湅棰嗘枡鍑哄簱鍗� */
-function handleDetail(row: MesWmProductIssueApi.ProductIssue) {
- formModalApi.setData({ formType: 'detail', id: row.id }).open();
-}
-
-/** 缂栬緫棰嗘枡鍑哄簱鍗� */
-function handleEdit(row: MesWmProductIssueApi.ProductIssue) {
- formModalApi.setData({ formType: 'update', id: row.id }).open();
-}
-
-/** 鎵ц鎷h揣 */
-function handleStock(row: MesWmProductIssueApi.ProductIssue) {
- formModalApi.setData({ formType: 'stock', id: row.id }).open();
-}
-
-/** 瀹屾垚棰嗘枡鍑哄簱 */
-function handleFinish(row: MesWmProductIssueApi.ProductIssue) {
- formModalApi.setData({ formType: 'finish', id: row.id }).open();
-}
-
-/** 鎻愪氦棰嗘枡鍑哄簱鍗� */
-async function handleSubmit(row: MesWmProductIssueApi.ProductIssue) {
- await submitProductIssue(row.id!);
- message.success('鎻愪氦鎴愬姛');
- handleRefresh();
-}
-
-/** 鍒犻櫎棰嗘枡鍑哄簱鍗� */
-async function handleDelete(row: MesWmProductIssueApi.ProductIssue) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.code]),
- duration: 0,
- });
- try {
- await deleteProductIssue(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.code]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-/** 鍙栨秷棰嗘枡鍑哄簱鍗� */
-async function handleCancel(row: MesWmProductIssueApi.ProductIssue) {
- await cancelProductIssue(row.id!);
- message.success('鍙栨秷鎴愬姛');
- handleRefresh();
-}
-
-/** 瀵煎嚭琛ㄦ牸 */
-async function handleExport() {
- const data = await exportProductIssue(await gridApi.formApi.getValues());
- downloadFileFromBlobPart({ fileName: '棰嗘枡鍑哄簱鍗�.xls', source: data });
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- formOptions: {
- schema: useGridFormSchema(),
- },
- gridOptions: {
- columns: useGridColumns(),
- height: 'auto',
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }, formValues) => {
- return await getProductIssuePage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- ...formValues,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- search: true,
- },
- } as VxeTableGridOptions<MesWmProductIssueApi.ProductIssue>,
-});
-</script>
-
-<template>
- <Page auto-content-height><FormModal @success="handleRefresh" />
-
- <Grid table-title="棰嗘枡鍑哄簱鍗曞垪琛�">
- <template #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: $t('ui.actionTitle.create', ['棰嗘枡鍑哄簱鍗�']),
- type: 'primary',
- icon: ACTION_ICON.ADD,
- auth: ['mes:wm-product-issue:create'],
- onClick: handleCreate,
- },
- {
- label: $t('ui.actionTitle.export'),
- type: 'primary',
- icon: ACTION_ICON.DOWNLOAD,
- auth: ['mes:wm-product-issue:export'],
- onClick: handleExport,
- },
- ]"
- />
- </template>
- <template #code="{ row }">
- <Button type="link" @click="handleDetail(row)">
- {{ row.code }}
- </Button>
- </template>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- auth: ['mes:wm-product-issue:update'],
- ifShow: row.status === MesWmProductIssueStatusEnum.PREPARE,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.submit'),
- type: 'link',
- auth: ['mes:wm-product-issue:update'],
- ifShow: row.status === MesWmProductIssueStatusEnum.PREPARE,
- popConfirm: {
- title: '纭鎻愪氦璇ラ鏂欏嚭搴撳崟锛熸彁浜ゅ悗灏嗕笉鑳戒慨鏀广��',
- confirm: handleSubmit.bind(null, row),
- },
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- auth: ['mes:wm-product-issue:delete'],
- ifShow: row.status === MesWmProductIssueStatusEnum.PREPARE,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.code]),
- confirm: handleDelete.bind(null, row),
- },
- },
- {
- label: '鎵ц鎷h揣',
- type: 'link',
- auth: ['mes:wm-product-issue:update'],
- ifShow: row.status === MesWmProductIssueStatusEnum.APPROVING,
- onClick: handleStock.bind(null, row),
- },
- {
- label: '瀹屾垚',
- type: 'link',
- auth: ['mes:wm-product-issue:finish'],
- ifShow: row.status === MesWmProductIssueStatusEnum.APPROVED,
- onClick: handleFinish.bind(null, row),
- },
- {
- label: '鍙栨秷',
- type: 'link',
- danger: true,
- auth: ['mes:wm-product-issue:update'],
- ifShow:
- row.status === MesWmProductIssueStatusEnum.APPROVING ||
- row.status === MesWmProductIssueStatusEnum.APPROVED,
- popConfirm: {
- title: '纭鍙栨秷璇ラ鏂欏嚭搴撳崟锛熷彇娑堝悗涓嶅彲鎭㈠銆�',
- confirm: handleCancel.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </Page>
-</template>
diff --git a/src/views/productissue/modules/detail-form.vue b/src/views/productissue/modules/detail-form.vue
deleted file mode 100644
index 43faa4e..0000000
--- a/src/views/productissue/modules/detail-form.vue
+++ /dev/null
@@ -1,104 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmProductIssueDetailApi } from '#/api/mes/wm/productissue/detail';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createProductIssueDetail,
- getProductIssueDetail,
- updateProductIssueDetail,
-} from '#/api/mes/wm/productissue/detail';
-import { $t } from '#/locales';
-
-import { useDetailFormSchema } from '../data';
-
-const emit = defineEmits<{ success: [lineId: number] }>();
-const formData = ref<MesWmProductIssueDetailApi.ProductIssueDetail>();
-const issueId = ref<number>(); // 鎵�灞為鏂欏崟缂栧彿
-const lineId = ref<number>(); // 鎵�灞為鏂欏崟琛岀紪鍙�
-
-const getTitle = computed(() => {
- return formData.value?.id
- ? $t('ui.actionTitle.edit', ['鎷h揣鏄庣粏'])
- : $t('ui.actionTitle.create', ['鎷h揣鏄庣粏']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 90,
- },
- layout: 'horizontal',
- schema: useDetailFormSchema(),
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data =
- (await formApi.getValues()) as MesWmProductIssueDetailApi.ProductIssueDetail;
- data.issueId = issueId.value;
- data.lineId = lineId.value;
- try {
- await (formData.value?.id
- ? updateProductIssueDetail({ ...data, id: formData.value.id })
- : createProductIssueDetail(data));
- // 鍏抽棴骞舵彁绀�
- await modalApi.close();
- emit('success', lineId.value!);
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- return;
- }
- formApi.setState({ schema: useDetailFormSchema(formApi) });
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{
- detailId?: number;
- issueId: number;
- itemId?: number;
- lineId: number;
- }>();
- issueId.value = data.issueId;
- lineId.value = data.lineId;
- if (data.detailId) {
- modalApi.lock();
- try {
- formData.value = await getProductIssueDetail(data.detailId);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- } else if (data.itemId) {
- await formApi.setFieldValue('itemId', data.itemId);
- }
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- </Modal>
-</template>
diff --git a/src/views/productissue/modules/detail-list.vue b/src/views/productissue/modules/detail-list.vue
deleted file mode 100644
index 769a8b7..0000000
--- a/src/views/productissue/modules/detail-list.vue
+++ /dev/null
@@ -1,105 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmProductIssueDetailApi } from '#/api/mes/wm/productissue/detail';
-
-import { computed, watch } from 'vue';
-
-import { message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import { deleteProductIssueDetail } from '#/api/mes/wm/productissue/detail';
-import { $t } from '#/locales';
-
-import { useDetailGridColumns } from '../data';
-
-const props = defineProps<{
- details: MesWmProductIssueDetailApi.ProductIssueDetail[];
- formType: FormType;
-}>();
-
-const emit = defineEmits<{
- edit: [detailId: number];
- refresh: [];
-}>();
-
-const isStock = computed(() => props.formType === 'stock'); // 鏄惁涓烘嫞璐фā寮�
-
-/** 缂栬緫鎷h揣鏄庣粏 */
-function handleEdit(row: MesWmProductIssueDetailApi.ProductIssueDetail) {
- emit('edit', row.id!);
-}
-
-/** 鍒犻櫎鎷h揣鏄庣粏 */
-async function handleDelete(
- row: MesWmProductIssueDetailApi.ProductIssueDetail,
-) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.warehouseName]),
- duration: 0,
- });
- try {
- await deleteProductIssueDetail(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.warehouseName]));
- emit('refresh');
- } finally {
- hideLoading();
- }
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- gridOptions: {
- border: true,
- columns: useDetailGridColumns(isStock.value),
- data: props.details,
- pagerConfig: {
- enabled: false,
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- size: 'small',
- toolbarConfig: {
- enabled: false,
- },
- } as VxeTableGridOptions<MesWmProductIssueDetailApi.ProductIssueDetail>,
-});
-
-watch(
- () => props.details,
- (details) => gridApi.setGridOptions({ data: details }),
-);
-</script>
-
-<template>
- <div class="px-4 py-2">
- <Grid>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [
- row.warehouseName,
- ]),
- confirm: handleDelete.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </div>
-</template>
diff --git a/src/views/productissue/modules/form.vue b/src/views/productissue/modules/form.vue
deleted file mode 100644
index e894b66..0000000
--- a/src/views/productissue/modules/form.vue
+++ /dev/null
@@ -1,232 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { MesWmProductIssueApi } from '#/api/mes/wm/productissue';
-
-import { computed, ref } from 'vue';
-
-import { confirm, useVbenModal } from '@vben/common-ui';
-import { MesWmProductIssueStatusEnum } from '@vben/constants';
-
-import { Button, Divider, message, Popconfirm } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- checkProductIssueQuantity,
- createProductIssue,
- finishProductIssue,
- getProductIssue,
- stockProductIssue,
- submitProductIssue,
- updateProductIssue,
-} from '#/api/mes/wm/productissue';
-import { $t } from '#/locales';
-
-import { useFormSchema } from '../data';
-import LineList from './line-list.vue';
-
-const emit = defineEmits(['success']);
-const formType = ref<FormType>('create');
-const formData = ref<MesWmProductIssueApi.ProductIssue>();
-const originalSnapshot = ref(''); // 琛ㄥ崟鍘熷鏁版嵁蹇収锛岀敤浜庢彁浜ゆ椂璺宠繃鏈彉鏇寸殑淇濆瓨璇锋眰
-const isEditable = computed(() =>
- // 鏄惁涓虹紪杈戞ā寮忥紙鍙繚瀛橈級
- ['create', 'update'].includes(formType.value),
-);
-const isStock = computed(() => formType.value === 'stock'); // 鏄惁涓烘嫞璐фā寮�
-const isFinish = computed(() => formType.value === 'finish'); // 鏄惁涓哄畬鎴愬嚭搴撴ā寮�
-const canSubmit = computed(
- () =>
- // 鏄惁鍙彁浜�
- formType.value === 'update' &&
- formData.value?.status === MesWmProductIssueStatusEnum.PREPARE,
-);
-const getTitle = computed(() => {
- if (formType.value === 'detail') {
- return $t('ui.actionTitle.view', ['棰嗘枡鍑哄簱鍗�']);
- }
- if (formType.value === 'stock') {
- return '鎵ц鎷h揣';
- }
- if (formType.value === 'finish') {
- return '瀹屾垚棰嗘枡鍑哄簱';
- }
- return formType.value === 'update'
- ? $t('ui.actionTitle.edit', ['棰嗘枡鍑哄簱鍗�'])
- : $t('ui.actionTitle.create', ['棰嗘枡鍑哄簱鍗�']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 110,
- },
- layout: 'horizontal',
- schema: [],
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-/** 鎻愪氦棰嗘枡鍗曪細琛ㄥ崟鏈変慨鏀规椂鍏堜繚瀛橈紝鍐嶈皟鐢ㄦ彁浜ゆ帴鍙� */
-async function handleSubmit() {
- const { valid } = await formApi.validate();
- if (!valid || !formData.value?.id) {
- return;
- }
- modalApi.lock();
- try {
- const current = JSON.stringify(await formApi.getValues());
- if (current !== originalSnapshot.value) {
- const data =
- (await formApi.getValues()) as MesWmProductIssueApi.ProductIssue;
- await updateProductIssue({ ...formData.value, ...data });
- originalSnapshot.value = current;
- }
- await submitProductIssue(formData.value.id);
- message.success('鎻愪氦鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-/** 鎵ц鎷h揣锛氶鏂欐暟閲忎笌鎷h揣鏁伴噺涓嶄竴鑷存椂浜屾纭 */
-async function handleStock() {
- if (!formData.value?.id) {
- return;
- }
- const quantityMatch = await checkProductIssueQuantity(formData.value.id);
- if (!quantityMatch) {
- try {
- await confirm('棰嗘枡鏁伴噺涓庢嫞璐ф暟閲忎笉涓�鑷达紝纭鎵ц鎷h揣锛�');
- } catch {
- return;
- }
- }
- modalApi.lock();
- try {
- await stockProductIssue(formData.value.id);
- message.success('鎷h揣鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-/** 瀹屾垚棰嗘枡鍑哄簱 */
-async function handleFinish() {
- if (!formData.value?.id) {
- return;
- }
- modalApi.lock();
- try {
- await finishProductIssue(formData.value.id);
- message.success('瀹屾垚鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- if (!isEditable.value) {
- await modalApi.close();
- return;
- }
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data =
- (await formApi.getValues()) as MesWmProductIssueApi.ProductIssue;
- try {
- if (formData.value?.id) {
- await updateProductIssue({ ...formData.value, ...data });
- formData.value = { ...formData.value, ...data };
- } else {
- const id = await createProductIssue(data);
- formData.value = {
- ...data,
- id,
- status: MesWmProductIssueStatusEnum.PREPARE,
- };
- await formApi.setFieldValue('id', id);
- await formApi.setFieldValue('status', formData.value.status);
- formType.value = 'update';
- }
- originalSnapshot.value = JSON.stringify(await formApi.getValues());
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- originalSnapshot.value = '';
- return;
- }
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{ formType: FormType; id?: number }>();
- formType.value = data.formType;
- formApi.setState({ schema: useFormSchema(formType.value, formApi) });
- formApi.setDisabled(!isEditable.value);
- modalApi.setState({ showConfirmButton: isEditable.value });
- if (data?.id) {
- modalApi.lock();
- try {
- formData.value = await getProductIssue(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- }
- originalSnapshot.value = JSON.stringify(await formApi.getValues());
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- <!-- 闈炴柊寤烘ā寮忓睍绀虹墿鏂欎俊鎭� -->
- <template v-if="formData?.id">
- <Divider>鐗╂枡淇℃伅</Divider>
- <div class="mx-4">
- <LineList :form-type="formType" :issue-id="formData.id" />
- </div>
- </template>
- <template #prepend-footer>
- <div class="flex flex-auto items-center gap-2">
- <Popconfirm
- v-if="canSubmit"
- title="纭鎻愪氦璇ラ鏂欏嚭搴撳崟锛熴�愭彁浜ゅ悗灏嗕笉鑳戒慨鏀广��"
- @confirm="handleSubmit"
- >
- <Button type="primary">鎻愪氦</Button>
- </Popconfirm>
- <Button v-if="isStock" type="primary" @click="handleStock">
- 鎵ц鎷h揣
- </Button>
- <Popconfirm
- v-if="isFinish"
- title="纭瀹屾垚璇ラ鏂欏崟骞舵墽琛屽嚭搴撳悧锛�"
- @confirm="handleFinish"
- >
- <Button type="primary">瀹屾垚</Button>
- </Popconfirm>
- </div>
- </template>
- </Modal>
-</template>
diff --git a/src/views/productissue/modules/line-form.vue b/src/views/productissue/modules/line-form.vue
deleted file mode 100644
index 8bf9782..0000000
--- a/src/views/productissue/modules/line-form.vue
+++ /dev/null
@@ -1,94 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmProductIssueLineApi } from '#/api/mes/wm/productissue/line';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createProductIssueLine,
- getProductIssueLine,
- updateProductIssueLine,
-} from '#/api/mes/wm/productissue/line';
-import { $t } from '#/locales';
-
-import { useLineFormSchema } from '../data';
-
-const emit = defineEmits(['success']);
-const formData = ref<MesWmProductIssueLineApi.ProductIssueLine>();
-const issueId = ref<number>(); // 鎵�灞為鏂欏崟缂栧彿
-
-const getTitle = computed(() => {
- return formData.value?.id
- ? $t('ui.actionTitle.edit', ['棰嗘枡鍑哄簱鍗曡'])
- : $t('ui.actionTitle.create', ['棰嗘枡鍑哄簱鍗曡']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 90,
- },
- layout: 'horizontal',
- schema: useLineFormSchema(),
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data =
- (await formApi.getValues()) as MesWmProductIssueLineApi.ProductIssueLine;
- data.issueId = issueId.value;
- try {
- await (formData.value?.id
- ? updateProductIssueLine({ ...data, id: formData.value.id })
- : createProductIssueLine(data));
- // 鍏抽棴骞舵彁绀�
- await modalApi.close();
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- return;
- }
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{ id?: number; issueId: number }>();
- issueId.value = data.issueId;
- if (!data.id) {
- return;
- }
- modalApi.lock();
- try {
- formData.value = await getProductIssueLine(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- </Modal>
-</template>
diff --git a/src/views/productissue/modules/line-list.vue b/src/views/productissue/modules/line-list.vue
deleted file mode 100644
index 7b83523..0000000
--- a/src/views/productissue/modules/line-list.vue
+++ /dev/null
@@ -1,223 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmProductIssueDetailApi } from '#/api/mes/wm/productissue/detail';
-import type { MesWmProductIssueLineApi } from '#/api/mes/wm/productissue/line';
-
-import { computed, reactive } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import { getProductIssueDetailListByLineId } from '#/api/mes/wm/productissue/detail';
-import {
- deleteProductIssueLine,
- getProductIssueLinePage,
-} from '#/api/mes/wm/productissue/line';
-import { $t } from '#/locales';
-
-import { useLineGridColumns } from '../data';
-import DetailForm from './detail-form.vue';
-import DetailList from './detail-list.vue';
-import LineForm from './line-form.vue';
-
-const props = defineProps<{
- formType: FormType;
- issueId: number;
-}>();
-
-const isEditable = computed(() =>
- // 鏄惁鍙紪杈戞槑缁嗚
- ['create', 'update'].includes(props.formType),
-);
-const isStock = computed(() => props.formType === 'stock'); // 鏄惁涓烘嫞璐фā寮�
-const detailMap = reactive<
- Record<number, MesWmProductIssueDetailApi.ProductIssueDetail[]>
->({}); // 宸插睍寮�琛岀殑鎷h揣鏄庣粏缂撳瓨
-
-const [LineFormModal, lineFormModalApi] = useVbenModal({
- connectedComponent: LineForm,
- destroyOnClose: true,
-});
-
-const [DetailFormModal, detailFormModalApi] = useVbenModal({
- connectedComponent: DetailForm,
- destroyOnClose: true,
-});
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- for (const id of Object.keys(detailMap)) {
- delete detailMap[Number(id)];
- }
- gridApi.query();
-}
-
-/** 娣诲姞鐗╂枡 */
-function handleCreate() {
- lineFormModalApi.setData({ issueId: props.issueId }).open();
-}
-
-/** 缂栬緫鐗╂枡 */
-function handleEdit(row: MesWmProductIssueLineApi.ProductIssueLine) {
- lineFormModalApi.setData({ id: row.id, issueId: props.issueId }).open();
-}
-
-/** 鍒犻櫎鐗╂枡 */
-async function handleDelete(row: MesWmProductIssueLineApi.ProductIssueLine) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.itemName]),
- duration: 0,
- });
- try {
- await deleteProductIssueLine(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.itemName]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-/** 鎷h揣锛氱洿鎺ユ墦寮�鏄庣粏鍒涘缓琛ㄥ崟 */
-function handlePicking(row: MesWmProductIssueLineApi.ProductIssueLine) {
- openDetailForm(row.id!, row.itemId);
-}
-
-/** 鎵撳紑鎷h揣鏄庣粏琛ㄥ崟 */
-function openDetailForm(lineId: number, itemId?: number, detailId?: number) {
- detailFormModalApi
- .setData({ detailId, issueId: props.issueId, itemId, lineId })
- .open();
-}
-
-/** 鑾峰彇宸插睍寮�琛岀殑鎷h揣鏄庣粏 */
-function getExpandedDetails(row: MesWmProductIssueLineApi.ProductIssueLine) {
- return detailMap[row.id!] || [];
-}
-
-/** 鍔犺浇鎸囧畾琛岀殑鎷h揣鏄庣粏 */
-async function loadLineDetails(lineId: number) {
- detailMap[lineId] = await getProductIssueDetailListByLineId(lineId);
-}
-
-/** 灞曞紑琛屾椂鎳掑姞杞芥嫞璐ф槑缁� */
-async function handleExpandChange(
- row: MesWmProductIssueLineApi.ProductIssueLine,
- expanded: boolean,
-) {
- if (!expanded) {
- return;
- }
- await loadLineDetails(row.id!);
-}
-
-/** 鏄庣粏琛ㄥ崟鎻愪氦鎴愬姛鍚庯紝鍒锋柊瀵瑰簲琛屽凡灞曞紑鐨勬槑缁� */
-async function handleDetailSuccess(lineId: number) {
- await loadLineDetails(lineId);
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- gridOptions: {
- columns: useLineGridColumns(isEditable.value, isStock.value),
- expandConfig: {
- padding: true,
- },
- height: 400,
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }) => {
- if (!props.issueId) {
- return { list: [], total: 0 };
- }
- return await getProductIssueLinePage({
- issueId: props.issueId,
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- },
- } as VxeTableGridOptions<MesWmProductIssueLineApi.ProductIssueLine>,
- gridEvents: {
- toggleRowExpand: ({
- expanded,
- row,
- }: {
- expanded: boolean;
- row: MesWmProductIssueLineApi.ProductIssueLine;
- }) => {
- handleExpandChange(row, expanded);
- },
- },
-});
-</script>
-
-<template>
- <div>
- <LineFormModal @success="handleRefresh" />
- <DetailFormModal @success="handleDetailSuccess" />
- <Grid table-title="鐗╂枡淇℃伅">
- <template v-if="isEditable" #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: '娣诲姞鐗╂枡',
- type: 'primary',
- icon: ACTION_ICON.ADD,
- onClick: handleCreate,
- },
- ]"
- />
- </template>
- <template #detail="{ row }">
- <DetailList
- :details="getExpandedDetails(row)"
- :form-type="formType"
- @edit="(detailId) => openDetailForm(row.id!, row.itemId, detailId)"
- @refresh="loadLineDetails(row.id!)"
- />
- </template>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- ifShow: isEditable,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- ifShow: isEditable,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.itemName]),
- confirm: handleDelete.bind(null, row),
- },
- },
- {
- label: '鎷h揣',
- type: 'link',
- ifShow: isStock,
- onClick: handlePicking.bind(null, row),
- },
- ]"
- />
- </template>
- </Grid>
- </div>
-</template>
diff --git a/src/views/productreceipt/data.ts b/src/views/productreceipt/data.ts
deleted file mode 100644
index 431138e..0000000
--- a/src/views/productreceipt/data.ts
+++ /dev/null
@@ -1,452 +0,0 @@
-锘縤mport type { VbenFormApi, VbenFormSchema } from '#/adapter/form';
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmMaterialStockApi } from '#/api/mes/wm/materialstock';
-import type { MesWmProductReceiptApi } from '#/api/mes/wm/productreceipt';
-import type { MesWmProductReceiptDetailApi } from '#/api/mes/wm/productreceipt/detail';
-import type { MesWmProductReceiptLineApi } from '#/api/mes/wm/productreceipt/line';
-
-import { h, markRaw } from 'vue';
-
-import {
- DICT_TYPE,
- MesAutoCodeRuleCode,
- MesProWorkOrderStatusEnum,
-} from '@vben/constants';
-
-import { Button } from 'ant-design-vue';
-
-import { generateAutoCode } from '#/api/mes/md/autocode/record';
-import { getRangePickerDefaultProps } from '#/utils';
-import { MdItemSelect } from '#/views/mes/md/item/components';
-import { ProWorkOrderSelect } from '#/views/mes/pro/workorder/components';
-import { WmMaterialStockSelect } from '#/views/wls/materialstock/components';
-import {
- WmWarehouseAreaSelect,
- WmWarehouseLocationSelect,
- WmWarehouseSelect,
-} from '#/views/wls/warehouse/components';
-
-/** 琛ㄥ崟绫诲瀷 */
-export type FormType = 'create' | 'detail' | 'finish' | 'stock' | 'update';
-
-/** 琛ㄥ崟澶撮儴鏄惁鍙锛堜笂鏋躲�佽鎯呫�佸叆搴撴�侊級 */
-function isHeaderReadonly(formType: FormType): boolean {
- return formType === 'detail' || formType === 'finish' || formType === 'stock';
-}
-
-/** 鏂板/淇敼鐨勮〃鍗� */
-export function useFormSchema(
- formType: FormType,
- formApi?: VbenFormApi,
-): VbenFormSchema[] {
- return [
- {
- fieldName: 'id',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'status',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'code',
- label: '鍏ュ簱鍗曠紪鍙�',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ュ叆搴撳崟缂栧彿',
- },
- rules: 'required',
- suffix: isHeaderReadonly(formType)
- ? undefined
- : () =>
- h(
- Button,
- {
- type: 'default',
- onClick: async () => {
- const code = await generateAutoCode(
- MesAutoCodeRuleCode.PRODUCTRECPT_CODE,
- );
- await formApi?.setFieldValue('code', code);
- },
- },
- { default: () => '鐢熸垚' },
- ),
- },
- {
- fieldName: 'name',
- label: '鍏ュ簱鍗曞悕绉�',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ュ叆搴撳崟鍚嶇О',
- },
- rules: 'required',
- },
- {
- fieldName: 'receiptDate',
- label: '鍏ュ簱鏃ユ湡',
- component: 'DatePicker',
- componentProps: {
- class: '!w-full',
- format: 'YYYY-MM-DD',
- placeholder: '璇烽�夋嫨鍏ュ簱鏃ユ湡',
- valueFormat: 'x',
- },
- rules: 'required',
- },
- {
- fieldName: 'workOrderId',
- label: '鐢熶骇璁㈠崟',
- component: markRaw(ProWorkOrderSelect),
- componentProps: {
- status: MesProWorkOrderStatusEnum.CONFIRMED,
- },
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勬悳绱㈣〃鍗� */
-export function useGridFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'code',
- label: '鍏ュ簱鍗曠紪鍙�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ュ叆搴撳崟缂栧彿',
- },
- },
- {
- fieldName: 'name',
- label: '鍏ュ簱鍗曞悕绉�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ュ叆搴撳崟鍚嶇О',
- },
- },
- {
- fieldName: 'receiptDate',
- label: '鍏ュ簱鏃ユ湡',
- component: 'RangePicker',
- componentProps: {
- ...getRangePickerDefaultProps(),
- allowClear: true,
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勫瓧娈� */
-export function useGridColumns(): VxeTableGridOptions<MesWmProductReceiptApi.ProductReceipt>['columns'] {
- return [
- {
- field: 'code',
- title: '鍏ュ簱鍗曠紪鍙�',
- minWidth: 160,
- slots: { default: 'code' },
- },
- {
- field: 'name',
- title: '鍏ュ簱鍗曞悕绉�',
- minWidth: 150,
- },
- {
- field: 'workOrderCode',
- title: '鐢熶骇璁㈠崟',
- minWidth: 140,
- },
- {
- field: 'receiptDate',
- title: '鍏ュ簱鏃ユ湡',
- width: 180,
- formatter: 'formatDate',
- },
- {
- field: 'status',
- title: '鍗曟嵁鐘舵��',
- minWidth: 110,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_PRODUCT_RECEIPT_STATUS },
- },
- },
- {
- title: '鎿嶄綔',
- width: 240,
- fixed: 'right',
- slots: { default: 'actions' },
- },
- ];
-}
-
-/** 鍏ュ簱鍗曡瀛愯〃鐨勫瓧娈� */
-export function useLineGridColumns(
- editable: boolean,
- stockable: boolean,
-): VxeTableGridOptions<MesWmProductReceiptLineApi.ProductReceiptLine>['columns'] {
- return [
- {
- type: 'expand',
- width: 48,
- slots: { content: 'detail' },
- },
- {
- field: 'itemCode',
- title: '浜у搧鐗╂枡缂栫爜',
- minWidth: 120,
- },
- {
- field: 'itemName',
- title: '浜у搧鐗╂枡鍚嶇О',
- minWidth: 140,
- },
- {
- field: 'specification',
- title: '瑙勬牸鍨嬪彿',
- minWidth: 120,
- },
- {
- field: 'unitMeasureName',
- title: '鍗曚綅',
- width: 80,
- },
- {
- field: 'quantity',
- title: '鍏ュ簱鏁伴噺',
- width: 100,
- },
- {
- field: 'batchCode',
- title: '鎵规鍙�',
- minWidth: 120,
- },
- ...(editable || stockable
- ? [
- {
- title: '鎿嶄綔',
- width: 200,
- fixed: 'right',
- slots: { default: 'actions' },
- } as const,
- ]
- : []),
- ];
-}
-
-/** 鍏ュ簱鍗曡鏂板/淇敼鐨勮〃鍗� */
-export function useLineFormSchema(formApi?: VbenFormApi): VbenFormSchema[] {
- return [
- {
- fieldName: 'materialStockId',
- label: '搴撳瓨璁板綍',
- component: markRaw(WmMaterialStockSelect),
- componentProps: {
- // 閫夋嫨搴撳瓨璁板綍鍚庯紝鑷姩鍥炲~鐗╂枡/鎵规/鏁伴噺
- onChange: async (stock?: MesWmMaterialStockApi.MaterialStock) => {
- await formApi?.setValues({
- batchCode: stock?.batchCode,
- batchId: stock?.batchId,
- itemId: stock?.itemId,
- quantity: stock?.quantity,
- quantityMax: stock?.quantity,
- });
- },
- virtualFilter: 'only',
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'quantityMax',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'quantity',
- label: '鍏ュ簱鏁伴噺',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0,
- placeholder: '璇疯緭鍏ュ叆搴撴暟閲�',
- precision: 2,
- },
- rules: 'required',
- dependencies: {
- triggerFields: ['quantityMax'],
- componentProps: (values) => ({
- class: '!w-full',
- max: values.quantityMax,
- min: 0,
- placeholder: '璇疯緭鍏ュ叆搴撴暟閲�',
- precision: 2,
- }),
- },
- },
- {
- fieldName: 'batchCode',
- label: '鎵规鍙�',
- component: 'Input',
- componentProps: {
- disabled: true,
- placeholder: '閫夋嫨搴撳瓨鍚庤嚜鍔ㄥ甫鍑�',
- },
- },
- {
- fieldName: 'itemId',
- label: '鐗╂枡',
- component: markRaw(MdItemSelect),
- componentProps: {
- disabled: true,
- },
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
-
-/** 涓婃灦鏄庣粏瀛愯〃鐨勫瓧娈� */
-export function useDetailGridColumns(
- stockable: boolean,
-): VxeTableGridOptions<MesWmProductReceiptDetailApi.ProductReceiptDetail>['columns'] {
- return [
- {
- field: 'warehouseName',
- title: '浠撳簱鍚嶇О',
- minWidth: 100,
- },
- {
- field: 'locationName',
- title: '搴撳尯鍚嶇О',
- minWidth: 100,
- },
- {
- field: 'areaName',
- title: '搴撲綅鍚嶇О',
- minWidth: 100,
- },
- {
- field: 'quantity',
- title: '鏁伴噺',
- width: 100,
- },
- ...(stockable
- ? [
- {
- title: '鎿嶄綔',
- width: 120,
- fixed: 'right',
- slots: { default: 'actions' },
- } as const,
- ]
- : []),
- ];
-}
-
-/** 涓婃灦鏄庣粏鏂板/淇敼鐨勮〃鍗� */
-export function useDetailFormSchema(formApi?: VbenFormApi): VbenFormSchema[] {
- return [
- {
- fieldName: 'itemId',
- label: '鐗╂枡',
- component: markRaw(MdItemSelect),
- componentProps: {
- disabled: true,
- },
- },
- {
- fieldName: 'warehouseId',
- label: '鍏ュ簱浠撳簱',
- component: markRaw(WmWarehouseSelect),
- componentProps: {
- // 鍒囨崲浠撳簱鍚庢竻绌哄簱鍖哄拰搴撲綅
- onChange: async () => {
- await formApi?.setValues({
- areaId: undefined,
- locationId: undefined,
- });
- },
- placeholder: '璇烽�夋嫨浠撳簱',
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'locationId',
- label: '搴撳尯',
- component: markRaw(WmWarehouseLocationSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨搴撳尯',
- },
- rules: 'selectRequired',
- dependencies: {
- triggerFields: ['warehouseId'],
- componentProps: (values) => ({
- // 鍒囨崲搴撳尯鍚庢竻绌哄簱浣�
- onChange: async () => {
- await formApi?.setFieldValue('areaId', undefined);
- },
- placeholder: '璇烽�夋嫨搴撳尯',
- warehouseId: values.warehouseId,
- }),
- },
- },
- {
- fieldName: 'areaId',
- label: '搴撲綅',
- component: markRaw(WmWarehouseAreaSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨搴撲綅',
- },
- rules: 'selectRequired',
- dependencies: {
- triggerFields: ['locationId'],
- componentProps: (values) => ({
- locationId: values.locationId,
- placeholder: '璇烽�夋嫨搴撲綅',
- }),
- },
- },
- {
- fieldName: 'quantity',
- label: '鏁伴噺',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0,
- placeholder: '璇疯緭鍏ユ暟閲�',
- precision: 2,
- },
- rules: 'required',
- },
- ];
-}
diff --git a/src/views/productreceipt/index.vue b/src/views/productreceipt/index.vue
deleted file mode 100644
index f557590..0000000
--- a/src/views/productreceipt/index.vue
+++ /dev/null
@@ -1,201 +0,0 @@
-<script lang="ts" setup>
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmProductReceiptApi } from '#/api/mes/wm/productreceipt';
-
-import { Page, useVbenModal } from '@vben/common-ui';
-import { MesWmProductReceiptStatusEnum } from '@vben/constants';
-import { downloadFileFromBlobPart } from '@vben/utils';
-
-import { Button, message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import {
- cancelProductReceipt,
- deleteProductReceipt,
- exportProductReceipt,
- getProductReceiptPage,
-} from '#/api/mes/wm/productreceipt';
-import { $t } from '#/locales';
-
-import { useGridColumns, useGridFormSchema } from './data';
-import Form from './modules/form.vue';
-
-const [FormModal, formModalApi] = useVbenModal({
- connectedComponent: Form,
- destroyOnClose: true,
-});
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- gridApi.query();
-}
-
-/** 鍒涘缓浜у搧鍏ュ簱鍗� */
-function handleCreate() {
- formModalApi.setData({ formType: 'create' }).open();
-}
-
-/** 鏌ョ湅浜у搧鍏ュ簱鍗� */
-function handleDetail(row: MesWmProductReceiptApi.ProductReceipt) {
- formModalApi.setData({ formType: 'detail', id: row.id }).open();
-}
-
-/** 缂栬緫浜у搧鍏ュ簱鍗� */
-function handleEdit(row: MesWmProductReceiptApi.ProductReceipt) {
- formModalApi.setData({ formType: 'update', id: row.id }).open();
-}
-
-/** 鎵ц涓婃灦 */
-function handleStock(row: MesWmProductReceiptApi.ProductReceipt) {
- formModalApi.setData({ formType: 'stock', id: row.id }).open();
-}
-
-/** 鎵ц鍏ュ簱 */
-function handleFinish(row: MesWmProductReceiptApi.ProductReceipt) {
- formModalApi.setData({ formType: 'finish', id: row.id }).open();
-}
-
-/** 鍒犻櫎浜у搧鍏ュ簱鍗� */
-async function handleDelete(row: MesWmProductReceiptApi.ProductReceipt) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.code]),
- duration: 0,
- });
- try {
- await deleteProductReceipt(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.code]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-/** 鍙栨秷浜у搧鍏ュ簱鍗� */
-async function handleCancel(row: MesWmProductReceiptApi.ProductReceipt) {
- await cancelProductReceipt(row.id!);
- message.success('鍙栨秷鎴愬姛');
- handleRefresh();
-}
-
-/** 瀵煎嚭琛ㄦ牸 */
-async function handleExport() {
- const data = await exportProductReceipt(await gridApi.formApi.getValues());
- downloadFileFromBlobPart({ fileName: '浜у搧鍏ュ簱鍗�.xls', source: data });
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- formOptions: {
- schema: useGridFormSchema(),
- },
- gridOptions: {
- columns: useGridColumns(),
- height: 'auto',
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }, formValues) => {
- return await getProductReceiptPage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- ...formValues,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- search: true,
- },
- } as VxeTableGridOptions<MesWmProductReceiptApi.ProductReceipt>,
-});
-</script>
-
-<template>
- <Page auto-content-height><FormModal @success="handleRefresh" />
-
- <Grid table-title="浜у搧鍏ュ簱鍗曞垪琛�">
- <template #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: $t('ui.actionTitle.create', ['浜у搧鍏ュ簱鍗�']),
- type: 'primary',
- icon: ACTION_ICON.ADD,
- auth: ['mes:wm-product-receipt:create'],
- onClick: handleCreate,
- },
- {
- label: $t('ui.actionTitle.export'),
- type: 'primary',
- icon: ACTION_ICON.DOWNLOAD,
- auth: ['mes:wm-product-receipt:export'],
- onClick: handleExport,
- },
- ]"
- />
- </template>
- <template #code="{ row }">
- <Button type="link" @click="handleDetail(row)">
- {{ row.code }}
- </Button>
- </template>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- auth: ['mes:wm-product-receipt:update'],
- ifShow: row.status === MesWmProductReceiptStatusEnum.PREPARE,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- auth: ['mes:wm-product-receipt:delete'],
- ifShow: row.status === MesWmProductReceiptStatusEnum.PREPARE,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.code]),
- confirm: handleDelete.bind(null, row),
- },
- },
- {
- label: '鎵ц涓婃灦',
- type: 'link',
- auth: ['mes:wm-product-receipt:update'],
- ifShow: row.status === MesWmProductReceiptStatusEnum.APPROVING,
- onClick: handleStock.bind(null, row),
- },
- {
- label: '鎵ц鍏ュ簱',
- type: 'link',
- auth: ['mes:wm-product-receipt:finish'],
- ifShow: row.status === MesWmProductReceiptStatusEnum.APPROVED,
- onClick: handleFinish.bind(null, row),
- },
- {
- label: '鍙栨秷',
- type: 'link',
- danger: true,
- auth: ['mes:wm-product-receipt:update'],
- ifShow:
- row.status === MesWmProductReceiptStatusEnum.APPROVING ||
- row.status === MesWmProductReceiptStatusEnum.APPROVED,
- popConfirm: {
- title: '纭鍙栨秷璇ヤ骇鍝佸叆搴撳崟锛熷彇娑堝悗涓嶅彲鎭㈠銆�',
- confirm: handleCancel.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </Page>
-</template>
diff --git a/src/views/productreceipt/modules/detail-form.vue b/src/views/productreceipt/modules/detail-form.vue
deleted file mode 100644
index b2a91c2..0000000
--- a/src/views/productreceipt/modules/detail-form.vue
+++ /dev/null
@@ -1,104 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmProductReceiptDetailApi } from '#/api/mes/wm/productreceipt/detail';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createProductReceiptDetail,
- getProductReceiptDetail,
- updateProductReceiptDetail,
-} from '#/api/mes/wm/productreceipt/detail';
-import { $t } from '#/locales';
-
-import { useDetailFormSchema } from '../data';
-
-const emit = defineEmits<{ success: [lineId: number] }>();
-const formData = ref<MesWmProductReceiptDetailApi.ProductReceiptDetail>();
-const receiptId = ref<number>(); // 鎵�灞炲叆搴撳崟缂栧彿
-const lineId = ref<number>(); // 鎵�灞炲叆搴撳崟琛岀紪鍙�
-
-const getTitle = computed(() => {
- return formData.value?.id
- ? $t('ui.actionTitle.edit', ['涓婃灦鏄庣粏'])
- : $t('ui.actionTitle.create', ['涓婃灦鏄庣粏']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 90,
- },
- layout: 'horizontal',
- schema: useDetailFormSchema(),
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data =
- (await formApi.getValues()) as MesWmProductReceiptDetailApi.ProductReceiptDetail;
- data.receiptId = receiptId.value;
- data.lineId = lineId.value;
- try {
- await (formData.value?.id
- ? updateProductReceiptDetail({ ...data, id: formData.value.id })
- : createProductReceiptDetail(data));
- // 鍏抽棴骞舵彁绀�
- await modalApi.close();
- emit('success', lineId.value!);
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- return;
- }
- formApi.setState({ schema: useDetailFormSchema(formApi) });
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{
- detailId?: number;
- itemId?: number;
- lineId: number;
- receiptId: number;
- }>();
- receiptId.value = data.receiptId;
- lineId.value = data.lineId;
- if (data.detailId) {
- modalApi.lock();
- try {
- formData.value = await getProductReceiptDetail(data.detailId);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- } else if (data.itemId) {
- await formApi.setFieldValue('itemId', data.itemId);
- }
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- </Modal>
-</template>
diff --git a/src/views/productreceipt/modules/detail-list.vue b/src/views/productreceipt/modules/detail-list.vue
deleted file mode 100644
index d4ec8c7..0000000
--- a/src/views/productreceipt/modules/detail-list.vue
+++ /dev/null
@@ -1,105 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmProductReceiptDetailApi } from '#/api/mes/wm/productreceipt/detail';
-
-import { computed, watch } from 'vue';
-
-import { message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import { deleteProductReceiptDetail } from '#/api/mes/wm/productreceipt/detail';
-import { $t } from '#/locales';
-
-import { useDetailGridColumns } from '../data';
-
-const props = defineProps<{
- details: MesWmProductReceiptDetailApi.ProductReceiptDetail[];
- formType: FormType;
-}>();
-
-const emit = defineEmits<{
- edit: [detailId: number];
- refresh: [];
-}>();
-
-const isStock = computed(() => props.formType === 'stock'); // 鏄惁涓轰笂鏋舵ā寮�
-
-/** 缂栬緫涓婃灦鏄庣粏 */
-function handleEdit(row: MesWmProductReceiptDetailApi.ProductReceiptDetail) {
- emit('edit', row.id!);
-}
-
-/** 鍒犻櫎涓婃灦鏄庣粏 */
-async function handleDelete(
- row: MesWmProductReceiptDetailApi.ProductReceiptDetail,
-) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.warehouseName]),
- duration: 0,
- });
- try {
- await deleteProductReceiptDetail(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.warehouseName]));
- emit('refresh');
- } finally {
- hideLoading();
- }
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- gridOptions: {
- border: true,
- columns: useDetailGridColumns(isStock.value),
- data: props.details,
- pagerConfig: {
- enabled: false,
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- size: 'small',
- toolbarConfig: {
- enabled: false,
- },
- } as VxeTableGridOptions<MesWmProductReceiptDetailApi.ProductReceiptDetail>,
-});
-
-watch(
- () => props.details,
- (details) => gridApi.setGridOptions({ data: details }),
-);
-</script>
-
-<template>
- <div class="px-4 py-2">
- <Grid>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [
- row.warehouseName,
- ]),
- confirm: handleDelete.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </div>
-</template>
diff --git a/src/views/productreceipt/modules/form.vue b/src/views/productreceipt/modules/form.vue
deleted file mode 100644
index d9fa648..0000000
--- a/src/views/productreceipt/modules/form.vue
+++ /dev/null
@@ -1,243 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { MesWmProductReceiptApi } from '#/api/mes/wm/productreceipt';
-
-import { computed, ref } from 'vue';
-
-import { confirm, useVbenModal } from '@vben/common-ui';
-import { MesWmProductReceiptStatusEnum } from '@vben/constants';
-
-import { Button, Divider, message, Popconfirm } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- checkProductReceiptQuantity,
- createProductReceipt,
- finishProductReceipt,
- getProductReceipt,
- stockProductReceipt,
- submitProductReceipt,
- updateProductReceipt,
-} from '#/api/mes/wm/productreceipt';
-import { $t } from '#/locales';
-
-import { useFormSchema } from '../data';
-import LineList from './line-list.vue';
-
-const emit = defineEmits(['success']);
-const formType = ref<FormType>('create');
-const formData = ref<MesWmProductReceiptApi.ProductReceipt>();
-const originalSnapshot = ref(''); // 琛ㄥ崟鍘熷鏁版嵁蹇収锛岀敤浜庢彁浜ゆ椂璺宠繃鏈彉鏇寸殑淇濆瓨璇锋眰
-const isEditable = computed(() =>
- // 鏄惁涓虹紪杈戞ā寮忥紙鍙繚瀛橈級
- ['create', 'update'].includes(formType.value),
-);
-const isStock = computed(() => formType.value === 'stock'); // 鏄惁涓轰笂鏋舵ā寮�
-const isFinish = computed(() => formType.value === 'finish'); // 鏄惁涓烘墽琛屽叆搴撴ā寮�
-const canSubmit = computed(
- () =>
- // 鏄惁鍙彁浜�
- formType.value === 'update' &&
- formData.value?.status === MesWmProductReceiptStatusEnum.PREPARE,
-);
-const getTitle = computed(() => {
- if (formType.value === 'detail') {
- return $t('ui.actionTitle.view', ['浜у搧鍏ュ簱鍗�']);
- }
- if (formType.value === 'stock') {
- return '鎵ц涓婃灦';
- }
- if (formType.value === 'finish') {
- return '鎵ц鍏ュ簱';
- }
- return formType.value === 'update'
- ? $t('ui.actionTitle.edit', ['浜у搧鍏ュ簱鍗�'])
- : $t('ui.actionTitle.create', ['浜у搧鍏ュ簱鍗�']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 110,
- },
- layout: 'horizontal',
- schema: [],
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-/** 鎻愪氦鍏ュ簱鍗曪細琛ㄥ崟鏈変慨鏀规椂鍏堜繚瀛橈紝鍐嶈皟鐢ㄦ彁浜ゆ帴鍙� */
-async function handleSubmit() {
- const { valid } = await formApi.validate();
- if (!valid || !formData.value?.id) {
- return;
- }
- modalApi.lock();
- try {
- const current = JSON.stringify(await formApi.getValues());
- if (current !== originalSnapshot.value) {
- const data =
- (await formApi.getValues()) as MesWmProductReceiptApi.ProductReceipt;
- await updateProductReceipt({ ...formData.value, ...data });
- originalSnapshot.value = current;
- }
- await submitProductReceipt(formData.value.id);
- message.success('鎻愪氦鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-/** 鎵ц涓婃灦锛氬厛纭锛屽啀鍦ㄦ槑缁嗘暟閲忎笌琛屾敹璐ф暟閲忎笉涓�鑷存椂浜屾纭 */
-async function handleStock() {
- if (!formData.value?.id) {
- return;
- }
- try {
- await confirm('纭鎵ц涓婃灦锛�');
- } catch {
- return;
- }
- const quantityMatch = await checkProductReceiptQuantity(formData.value.id);
- if (!quantityMatch) {
- try {
- await confirm('鏄庣粏鏁伴噺涓庤鏀惰揣鏁伴噺涓嶄竴鑷达紝纭鎵ц涓婃灦锛�');
- } catch {
- return;
- }
- }
- modalApi.lock();
- try {
- await stockProductReceipt(formData.value.id);
- message.success('涓婃灦鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-/** 鎵ц鍏ュ簱 */
-async function handleFinish() {
- if (!formData.value?.id) {
- return;
- }
- modalApi.lock();
- try {
- await finishProductReceipt(formData.value.id);
- message.success('鍏ュ簱鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- if (!isEditable.value) {
- await modalApi.close();
- return;
- }
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data =
- (await formApi.getValues()) as MesWmProductReceiptApi.ProductReceipt;
- try {
- if (formData.value?.id) {
- await updateProductReceipt({ ...formData.value, ...data });
- formData.value = { ...formData.value, ...data };
- } else {
- const id = await createProductReceipt(data);
- formData.value = {
- ...data,
- id,
- status: MesWmProductReceiptStatusEnum.PREPARE,
- };
- await formApi.setFieldValue('id', id);
- await formApi.setFieldValue('status', formData.value.status);
- formType.value = 'update';
- }
- originalSnapshot.value = JSON.stringify(await formApi.getValues());
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- originalSnapshot.value = '';
- return;
- }
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{ formType: FormType; id?: number }>();
- formType.value = data.formType;
- formApi.setState({ schema: useFormSchema(formType.value, formApi) });
- formApi.setDisabled(!isEditable.value);
- modalApi.setState({ showConfirmButton: isEditable.value });
- if (data?.id) {
- modalApi.lock();
- try {
- formData.value = await getProductReceipt(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- }
- originalSnapshot.value = JSON.stringify(await formApi.getValues());
- },
-});
-
-/** 鍏ュ簱鍓嶇‘璁� */
-async function confirmFinish() {
- try {
- await confirm('纭鎵ц鍏ュ簱锛熸墽琛屽悗灏嗘洿鏂板簱瀛樺彴璐︺��');
- } catch {
- return;
- }
- await handleFinish();
-}
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- <!-- 闈炴柊寤烘ā寮忓睍绀虹墿鏂欎俊鎭� -->
- <template v-if="formData?.id">
- <Divider>鐗╂枡淇℃伅</Divider>
- <div class="mx-4">
- <LineList :form-type="formType" :receipt-id="formData.id" />
- </div>
- </template>
- <template #prepend-footer>
- <div class="flex flex-auto items-center gap-2">
- <Popconfirm
- v-if="canSubmit"
- title="纭鎻愪氦璇ヤ骇鍝佸叆搴撳崟锛熴�愭彁浜ゅ悗灏嗕笉鑳戒慨鏀广��"
- @confirm="handleSubmit"
- >
- <Button type="primary">鎻愪氦</Button>
- </Popconfirm>
- <Button v-if="isStock" type="primary" @click="handleStock">
- 鎵ц涓婃灦
- </Button>
- <Button v-if="isFinish" type="primary" @click="confirmFinish">
- 鎵ц鍏ュ簱
- </Button>
- </div>
- </template>
- </Modal>
-</template>
diff --git a/src/views/productreceipt/modules/line-form.vue b/src/views/productreceipt/modules/line-form.vue
deleted file mode 100644
index b9e3716..0000000
--- a/src/views/productreceipt/modules/line-form.vue
+++ /dev/null
@@ -1,95 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmProductReceiptLineApi } from '#/api/mes/wm/productreceipt/line';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createProductReceiptLine,
- getProductReceiptLine,
- updateProductReceiptLine,
-} from '#/api/mes/wm/productreceipt/line';
-import { $t } from '#/locales';
-
-import { useLineFormSchema } from '../data';
-
-const emit = defineEmits(['success']);
-const formData = ref<MesWmProductReceiptLineApi.ProductReceiptLine>();
-const receiptId = ref<number>(); // 鎵�灞炲叆搴撳崟缂栧彿
-
-const getTitle = computed(() => {
- return formData.value?.id
- ? $t('ui.actionTitle.edit', ['鐗╂枡鍏ュ簱鍗曡'])
- : $t('ui.actionTitle.create', ['鐗╂枡鍏ュ簱鍗曡']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 110,
- },
- layout: 'horizontal',
- schema: [],
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data =
- (await formApi.getValues()) as MesWmProductReceiptLineApi.ProductReceiptLine;
- data.receiptId = receiptId.value;
- try {
- await (formData.value?.id
- ? updateProductReceiptLine({ ...data, id: formData.value.id })
- : createProductReceiptLine(data));
- // 鍏抽棴骞舵彁绀�
- await modalApi.close();
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- return;
- }
- formApi.setState({ schema: useLineFormSchema(formApi) });
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{ id?: number; receiptId: number }>();
- receiptId.value = data.receiptId;
- if (!data.id) {
- return;
- }
- modalApi.lock();
- try {
- formData.value = await getProductReceiptLine(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- </Modal>
-</template>
diff --git a/src/views/productreceipt/modules/line-list.vue b/src/views/productreceipt/modules/line-list.vue
deleted file mode 100644
index 26442fb..0000000
--- a/src/views/productreceipt/modules/line-list.vue
+++ /dev/null
@@ -1,254 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmProductReceiptDetailApi } from '#/api/mes/wm/productreceipt/detail';
-import type { MesWmProductReceiptLineApi } from '#/api/mes/wm/productreceipt/line';
-
-import { computed, reactive, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-import { BarcodeBizTypeEnum } from '@vben/constants';
-
-import { message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import { getProductReceiptDetailListByLineId } from '#/api/mes/wm/productreceipt/detail';
-import {
- deleteProductReceiptLine,
- getProductReceiptLinePage,
-} from '#/api/mes/wm/productreceipt/line';
-import { $t } from '#/locales';
-import { BarcodeDetail, PrinterLabel } from '#/views/wls/barcode/components';
-
-import { useLineGridColumns } from '../data';
-import DetailForm from './detail-form.vue';
-import DetailList from './detail-list.vue';
-import LineForm from './line-form.vue';
-
-const props = defineProps<{
- formType: FormType;
- receiptId: number;
-}>();
-
-const isEditable = computed(() =>
- // 鏄惁鍙紪杈戞槑缁嗚
- ['create', 'update'].includes(props.formType),
-);
-const isStock = computed(() => props.formType === 'stock'); // 鏄惁涓轰笂鏋舵ā寮�
-const detailMap = reactive<
- Record<number, MesWmProductReceiptDetailApi.ProductReceiptDetail[]>
->({}); // 宸插睍寮�琛岀殑涓婃灦鏄庣粏缂撳瓨
-const barcodeDetailRef = ref(); // 鏉$爜璇︽儏寮圭獥瀹炰緥
-
-const [LineFormModal, lineFormModalApi] = useVbenModal({
- connectedComponent: LineForm,
- destroyOnClose: true,
-});
-
-const [DetailFormModal, detailFormModalApi] = useVbenModal({
- connectedComponent: DetailForm,
- destroyOnClose: true,
-});
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- for (const id of Object.keys(detailMap)) {
- delete detailMap[Number(id)];
- }
- gridApi.query();
-}
-
-/** 娣诲姞鐗╂枡 */
-function handleCreate() {
- lineFormModalApi.setData({ receiptId: props.receiptId }).open();
-}
-
-/** 缂栬緫鐗╂枡 */
-function handleEdit(row: MesWmProductReceiptLineApi.ProductReceiptLine) {
- lineFormModalApi.setData({ id: row.id, receiptId: props.receiptId }).open();
-}
-
-/** 鍒犻櫎鐗╂枡 */
-async function handleDelete(
- row: MesWmProductReceiptLineApi.ProductReceiptLine,
-) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.itemName]),
- duration: 0,
- });
- try {
- await deleteProductReceiptLine(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.itemName]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-/** 涓婃灦锛氱洿鎺ユ墦寮�鏄庣粏鍒涘缓琛ㄥ崟 */
-function handleStock(row: MesWmProductReceiptLineApi.ProductReceiptLine) {
- openDetailForm(row.id!, row.itemId);
-}
-
-/** 鏌ョ湅鐗╂枡鏉$爜 */
-function handleBarcode(row: MesWmProductReceiptLineApi.ProductReceiptLine) {
- barcodeDetailRef.value?.openByBusiness(
- row.itemId,
- BarcodeBizTypeEnum.ITEM,
- row.itemCode,
- row.itemName,
- );
-}
-
-/** 鎵撳紑涓婃灦鏄庣粏琛ㄥ崟 */
-function openDetailForm(lineId: number, itemId?: number, detailId?: number) {
- detailFormModalApi
- .setData({ detailId, itemId, lineId, receiptId: props.receiptId })
- .open();
-}
-
-/** 鑾峰彇宸插睍寮�琛岀殑涓婃灦鏄庣粏 */
-function getExpandedDetails(
- row: MesWmProductReceiptLineApi.ProductReceiptLine,
-) {
- return detailMap[row.id!] || [];
-}
-
-/** 鍔犺浇鎸囧畾琛岀殑涓婃灦鏄庣粏 */
-async function loadLineDetails(lineId: number) {
- detailMap[lineId] = await getProductReceiptDetailListByLineId(lineId);
-}
-
-/** 灞曞紑琛屾椂鎳掑姞杞戒笂鏋舵槑缁� */
-async function handleExpandChange(
- row: MesWmProductReceiptLineApi.ProductReceiptLine,
- expanded: boolean,
-) {
- if (!expanded) {
- return;
- }
- await loadLineDetails(row.id!);
-}
-
-/** 鏄庣粏琛ㄥ崟鎻愪氦鎴愬姛鍚庯紝鍒锋柊瀵瑰簲琛屽凡灞曞紑鐨勬槑缁� */
-async function handleDetailSuccess(lineId: number) {
- await loadLineDetails(lineId);
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- gridOptions: {
- columns: useLineGridColumns(isEditable.value, isStock.value),
- expandConfig: {
- padding: true,
- },
- height: 400,
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }) => {
- if (!props.receiptId) {
- return { list: [], total: 0 };
- }
- return await getProductReceiptLinePage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- receiptId: props.receiptId,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- },
- } as VxeTableGridOptions<MesWmProductReceiptLineApi.ProductReceiptLine>,
- gridEvents: {
- toggleRowExpand: ({
- expanded,
- row,
- }: {
- expanded: boolean;
- row: MesWmProductReceiptLineApi.ProductReceiptLine;
- }) => {
- handleExpandChange(row, expanded);
- },
- },
-});
-</script>
-
-<template>
- <div>
- <LineFormModal @success="handleRefresh" />
- <DetailFormModal @success="handleDetailSuccess" />
- <Grid table-title="鐗╂枡淇℃伅">
- <template v-if="isEditable" #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: '娣诲姞鐗╂枡',
- type: 'primary',
- icon: ACTION_ICON.ADD,
- onClick: handleCreate,
- },
- ]"
- />
- </template>
- <template #detail="{ row }">
- <DetailList
- :details="getExpandedDetails(row)"
- :form-type="formType"
- @edit="(detailId) => openDetailForm(row.id!, row.itemId, detailId)"
- @refresh="loadLineDetails(row.id!)"
- />
- </template>
- <template #actions="{ row }">
- <div class="flex items-center justify-center">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- ifShow: isEditable,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- ifShow: isEditable,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.itemName]),
- confirm: handleDelete.bind(null, row),
- },
- },
- {
- label: '涓婃灦',
- type: 'link',
- ifShow: isStock,
- onClick: handleStock.bind(null, row),
- },
- {
- label: '鏉$爜',
- type: 'link',
- onClick: handleBarcode.bind(null, row),
- },
- ]"
- />
- <PrinterLabel
- v-if="isStock"
- :biz-code="row.batchCode"
- :biz-id="row.batchId"
- biz-type="BATCH"
- />
- </div>
- </template>
- </Grid>
- <BarcodeDetail ref="barcodeDetailRef" />
- </div>
-</template>
diff --git a/src/views/productsales/data.ts b/src/views/productsales/data.ts
deleted file mode 100644
index a99cee4..0000000
--- a/src/views/productsales/data.ts
+++ /dev/null
@@ -1,701 +0,0 @@
-import type { VbenFormApi, VbenFormSchema } from '#/adapter/form';
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmMaterialStockApi } from '#/api/mes/wm/materialstock';
-import type { MesWmProductSalesApi } from '#/api/mes/wm/productsales';
-import type { MesWmProductSalesDetailApi } from '#/api/mes/wm/productsales/detail';
-import type { MesWmProductSalesLineApi } from '#/api/mes/wm/productsales/line';
-import type { MesWmSalesNoticeApi } from '#/api/mes/wm/salesnotice';
-import type { MesWmSalesNoticeLineApi } from '#/api/mes/wm/salesnotice/line';
-
-import { h, markRaw } from 'vue';
-
-import {
- DICT_TYPE,
- MesAutoCodeRuleCode,
- MesWmSalesNoticeStatusEnum,
-} from '@vben/constants';
-import { getDictOptions } from '@vben/hooks';
-
-import { Button } from 'ant-design-vue';
-
-import { z } from '#/adapter/form';
-import { generateAutoCode } from '#/api/mes/md/autocode/record';
-import { getRangePickerDefaultProps } from '#/utils';
-import { MdClientSelect } from '#/views/mes/md/client/components';
-import { MdItemSelect } from '#/views/mes/md/item/components';
-import { WmMaterialStockSelect } from '#/views/wls/materialstock/components';
-import {
- WmSalesNoticeLineSelect,
- WmSalesNoticeSelect,
-} from '#/views/wls/salesnotice/components';
-import {
- WmWarehouseAreaSelect,
- WmWarehouseLocationSelect,
- WmWarehouseSelect,
-} from '#/views/wls/warehouse/components';
-
-/** 琛ㄥ崟绫诲瀷 */
-export type FormType =
- | 'create'
- | 'detail'
- | 'finish'
- | 'shipping'
- | 'stock'
- | 'update';
-
-/** 琛ㄥ崟澶撮儴鏄惁鍙锛堟嫞璐с�佸~鍐欒繍鍗曘�佸嚭搴撱�佽鎯呮�侊級 */
-function isHeaderReadonly(formType: FormType): boolean {
- return (
- formType === 'detail' ||
- formType === 'finish' ||
- formType === 'shipping' ||
- formType === 'stock'
- );
-}
-
-/** 鏄惁灞曠ず杩愯緭淇℃伅 */
-export function showShippingInfo(formType: FormType): boolean {
- return (
- formType === 'shipping' || formType === 'detail' || formType === 'finish'
- );
-}
-
-/** 鏂板/淇敼鐨勮〃鍗� */
-export function useFormSchema(
- formType: FormType,
- formApi?: VbenFormApi,
-): VbenFormSchema[] {
- return [
- {
- fieldName: 'id',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'status',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'code',
- label: '鍑哄簱鍗曠紪鍙�',
- component: 'Input',
- componentProps: {
- disabled: isHeaderReadonly(formType),
- placeholder: '璇疯緭鍏ュ嚭搴撳崟缂栧彿',
- },
- rules: 'required',
- suffix: isHeaderReadonly(formType)
- ? undefined
- : () =>
- h(
- Button,
- {
- type: 'default',
- onClick: async () => {
- const code = await generateAutoCode(
- MesAutoCodeRuleCode.WM_PRODUCT_SALES_CODE,
- );
- await formApi?.setFieldValue('code', code);
- },
- },
- { default: () => '鐢熸垚' },
- ),
- },
- {
- fieldName: 'name',
- label: '鍑哄簱鍗曞悕绉�',
- component: 'Input',
- componentProps: {
- disabled: isHeaderReadonly(formType),
- placeholder: '璇疯緭鍏ュ嚭搴撳崟鍚嶇О',
- },
- rules: 'required',
- },
- {
- fieldName: 'noticeId',
- label: '鍙戣揣閫氱煡鍗�',
- component: markRaw(WmSalesNoticeSelect),
- componentProps: {
- disabled: isHeaderReadonly(formType),
- // 閫夋嫨鍙戣揣閫氱煡鍗曞悗锛岃嚜鍔ㄥ洖濉攢鍞鍗曞彿銆佸鎴枫�佹敹璐т汉淇℃伅
- onChange: async (notice?: MesWmSalesNoticeApi.SalesNotice) => {
- await formApi?.setValues({
- clientId: notice?.clientId,
- contactAddress: notice?.recipientAddress,
- contactName: notice?.recipientName,
- contactTelephone: notice?.recipientTelephone,
- salesOrderCode: notice?.salesOrderCode,
- });
- },
- status: MesWmSalesNoticeStatusEnum.APPROVED,
- },
- },
- {
- fieldName: 'salesOrderCode',
- label: '閿�鍞鍗曠紪鍙�',
- component: 'Input',
- componentProps: {
- disabled: isHeaderReadonly(formType),
- placeholder: '璇疯緭鍏ラ攢鍞鍗曠紪鍙�',
- },
- },
- {
- fieldName: 'salesDate',
- label: '鍑哄簱鏃ユ湡',
- component: 'DatePicker',
- componentProps: {
- class: '!w-full',
- disabled: isHeaderReadonly(formType),
- format: 'YYYY-MM-DD',
- placeholder: '璇烽�夋嫨鍑哄簱鏃ユ湡',
- valueFormat: 'x',
- },
- rules: 'required',
- },
- {
- fieldName: 'clientId',
- label: '瀹㈡埛',
- component: markRaw(MdClientSelect),
- componentProps: {
- disabled: isHeaderReadonly(formType),
- placeholder: '璇烽�夋嫨瀹㈡埛',
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'contactName',
- label: '鏀惰揣浜�',
- component: 'Input',
- componentProps: {
- disabled: isHeaderReadonly(formType),
- placeholder: '璇疯緭鍏ユ敹璐т汉',
- },
- },
- {
- fieldName: 'contactTelephone',
- label: '鑱旂郴鏂瑰紡',
- component: 'Input',
- componentProps: {
- disabled: isHeaderReadonly(formType),
- placeholder: '璇疯緭鍏ヨ仈绯绘柟寮�',
- },
- },
- {
- fieldName: 'contactAddress',
- label: '鏀惰揣鍦板潃',
- component: 'Input',
- componentProps: {
- disabled: isHeaderReadonly(formType),
- placeholder: '璇疯緭鍏ユ敹璐у湴鍧�',
- },
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- disabled: isHeaderReadonly(formType),
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- {
- fieldName: 'carrier',
- label: '鎵胯繍鍟�',
- component: 'Input',
- componentProps: {
- disabled: formType !== 'shipping',
- placeholder: '璇疯緭鍏ユ壙杩愬晢',
- },
- dependencies: {
- triggerFields: [''],
- if: () => showShippingInfo(formType),
- },
- },
- {
- fieldName: 'shippingNumber',
- label: '杩愯緭鍗曞彿',
- component: 'Input',
- componentProps: {
- disabled: formType !== 'shipping',
- placeholder: '璇疯緭鍏ヨ繍杈撳崟鍙�',
- },
- dependencies: {
- triggerFields: [''],
- if: () => showShippingInfo(formType),
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勬悳绱㈣〃鍗� */
-export function useGridFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'code',
- label: '鍑哄簱鍗曠紪鍙�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ュ嚭搴撳崟缂栧彿',
- },
- },
- {
- fieldName: 'name',
- label: '鍑哄簱鍗曞悕绉�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ュ嚭搴撳崟鍚嶇О',
- },
- },
- {
- fieldName: 'salesOrderCode',
- label: '閿�鍞鍗曠紪鍙�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ラ攢鍞鍗曠紪鍙�',
- },
- },
- {
- fieldName: 'clientId',
- label: '瀹㈡埛',
- component: markRaw(MdClientSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨瀹㈡埛',
- },
- },
- {
- fieldName: 'salesDate',
- label: '鍑哄簱鏃ユ湡',
- component: 'RangePicker',
- componentProps: {
- ...getRangePickerDefaultProps(),
- allowClear: true,
- },
- },
- {
- fieldName: 'status',
- label: '鍗曟嵁鐘舵��',
- component: 'Select',
- componentProps: {
- allowClear: true,
- options: getDictOptions(
- DICT_TYPE.MES_WM_PRODUCT_SALES_STATUS,
- 'number',
- ),
- placeholder: '璇烽�夋嫨鍗曟嵁鐘舵��',
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勫瓧娈� */
-export function useGridColumns(): VxeTableGridOptions<MesWmProductSalesApi.ProductSales>['columns'] {
- return [
- {
- field: 'code',
- title: '鍑哄簱鍗曠紪鍙�',
- minWidth: 160,
- slots: { default: 'code' },
- },
- {
- field: 'name',
- title: '鍑哄簱鍗曞悕绉�',
- minWidth: 150,
- },
- {
- field: 'noticeCode',
- title: '鍙戣揣閫氱煡鍗曞彿',
- minWidth: 160,
- },
- {
- field: 'salesOrderCode',
- title: '閿�鍞鍗曠紪鍙�',
- minWidth: 160,
- },
- {
- field: 'clientCode',
- title: '瀹㈡埛缂栫爜',
- minWidth: 120,
- },
- {
- field: 'clientName',
- title: '瀹㈡埛鍚嶇О',
- minWidth: 120,
- },
- {
- field: 'contactName',
- title: '鏀惰揣浜�',
- minWidth: 100,
- },
- {
- field: 'carrier',
- title: '鎵胯繍鍟�',
- minWidth: 120,
- },
- {
- field: 'shippingNumber',
- title: '杩愯緭鍗曞彿',
- minWidth: 160,
- },
- {
- field: 'salesDate',
- title: '鍑哄簱鏃ユ湡',
- width: 180,
- formatter: 'formatDate',
- },
- {
- field: 'status',
- title: '鍗曟嵁鐘舵��',
- minWidth: 100,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_PRODUCT_SALES_STATUS },
- },
- },
- {
- title: '鎿嶄綔',
- width: 240,
- fixed: 'right',
- slots: { default: 'actions' },
- },
- ];
-}
-
-/** 鍑哄簱鍗曡瀛愯〃鐨勫瓧娈� */
-export function useLineGridColumns(
- editable: boolean,
- stockable: boolean,
-): VxeTableGridOptions<MesWmProductSalesLineApi.ProductSalesLine>['columns'] {
- return [
- {
- type: 'expand',
- width: 48,
- slots: { content: 'detail' },
- },
- {
- field: 'itemCode',
- title: '浜у搧缂栫爜',
- minWidth: 120,
- },
- {
- field: 'itemName',
- title: '浜у搧鍚嶇О',
- minWidth: 140,
- },
- {
- field: 'specification',
- title: '瑙勬牸鍨嬪彿',
- minWidth: 120,
- },
- {
- field: 'unitMeasureName',
- title: '鍗曚綅',
- width: 80,
- },
- {
- field: 'quantity',
- title: '鍑哄簱鏁伴噺',
- width: 100,
- },
- {
- field: 'batchCode',
- title: '鎵规鍙�',
- minWidth: 120,
- },
- {
- field: 'oqcCheckFlag',
- title: '鏄惁鏍¢獙',
- width: 100,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.INFRA_BOOLEAN_STRING },
- },
- },
- {
- field: 'remark',
- title: '澶囨敞',
- minWidth: 150,
- },
- ...(editable || stockable
- ? [
- {
- title: '鎿嶄綔',
- width: 160,
- fixed: 'right',
- slots: { default: 'actions' },
- } as const,
- ]
- : []),
- ];
-}
-
-/** 鍑哄簱鍗曡鏂板/淇敼鐨勮〃鍗� */
-export function useLineFormSchema(
- hasNotice: boolean,
- formApi?: VbenFormApi,
-): VbenFormSchema[] {
- return [
- {
- fieldName: 'noticeId',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'noticeLineId',
- label: '鍙戣揣閫氱煡鍗曡',
- component: markRaw(WmSalesNoticeLineSelect),
- componentProps: {
- // 閫夋嫨鍙戣揣閫氱煡鍗曡鍚庯紝鑷姩鍥炲~鐗╂枡銆佹暟閲忋�佹壒娆°�佹槸鍚︽楠�
- onChange: async (line?: MesWmSalesNoticeLineApi.SalesNoticeLine) => {
- await formApi?.setValues({
- batchCode: line?.batchCode,
- itemId: line?.itemId,
- oqcCheckFlag: line?.oqcCheckFlag ?? false,
- quantity: line?.quantity,
- });
- },
- },
- dependencies: {
- triggerFields: ['noticeId'],
- if: () => hasNotice,
- componentProps: (values) => ({
- noticeId: values.noticeId,
- }),
- },
- },
- {
- fieldName: 'itemId',
- label: '浜у搧',
- component: markRaw(MdItemSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨浜у搧',
- },
- rules: 'selectRequired',
- dependencies: {
- triggerFields: ['noticeLineId'],
- componentProps: (values) => ({
- disabled: !!values.noticeLineId,
- placeholder: '璇烽�夋嫨浜у搧',
- }),
- },
- },
- {
- fieldName: 'batchCode',
- label: '鎵规鍙�',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ユ壒娆″彿',
- },
- },
- {
- fieldName: 'quantity',
- label: '鍑哄簱鏁伴噺',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0,
- placeholder: '璇疯緭鍏ュ嚭搴撴暟閲�',
- precision: 2,
- },
- rules: 'required',
- },
- {
- fieldName: 'oqcCheckFlag',
- label: '鏄惁鏍¢獙',
- component: 'RadioGroup',
- componentProps: {
- buttonStyle: 'solid',
- optionType: 'button',
- options: getDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING, 'boolean'),
- },
- rules: z.boolean().default(false),
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
-
-/** 鎷h揣鏄庣粏瀛愯〃鐨勫瓧娈� */
-export function useDetailGridColumns(
- stockable: boolean,
-): VxeTableGridOptions<MesWmProductSalesDetailApi.ProductSalesDetail>['columns'] {
- return [
- {
- field: 'warehouseName',
- title: '浠撳簱鍚嶇О',
- minWidth: 100,
- },
- {
- field: 'locationName',
- title: '搴撳尯鍚嶇О',
- minWidth: 100,
- },
- {
- field: 'areaName',
- title: '搴撲綅鍚嶇О',
- minWidth: 100,
- },
- {
- field: 'quantity',
- title: '鏁伴噺',
- width: 100,
- },
- ...(stockable
- ? [
- {
- title: '鎿嶄綔',
- width: 120,
- fixed: 'right',
- slots: { default: 'actions' },
- } as const,
- ]
- : []),
- ];
-}
-
-/** 鎷h揣鏄庣粏鏂板/淇敼鐨勮〃鍗� */
-export function useDetailFormSchema(formApi?: VbenFormApi): VbenFormSchema[] {
- return [
- {
- fieldName: 'quantityMax',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'batchId',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'itemId',
- label: '鐗╂枡',
- component: markRaw(MdItemSelect),
- componentProps: {
- disabled: true,
- },
- },
- {
- fieldName: 'materialStockId',
- label: '閫夋嫨搴撳瓨',
- component: markRaw(WmMaterialStockSelect),
- componentProps: {
- // 閫夋嫨搴撳瓨璁板綍鍚庯紝鑷姩鍥炲~浠撳簱/搴撳尯/搴撲綅/鎵规/鏁伴噺
- onChange: async (stock?: MesWmMaterialStockApi.MaterialStock) => {
- await formApi?.setValues({
- areaId: stock?.areaId,
- batchCode: stock?.batchCode,
- batchId: stock?.batchId,
- locationId: stock?.locationId,
- quantity: stock?.quantity,
- quantityMax: stock?.quantity,
- warehouseId: stock?.warehouseId,
- });
- },
- },
- rules: 'selectRequired',
- dependencies: {
- triggerFields: ['itemId', 'batchId'],
- componentProps: (values) => ({
- batchId: values.batchId,
- itemId: values.itemId,
- }),
- },
- },
- {
- fieldName: 'quantity',
- label: '鏁伴噺',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0,
- placeholder: '璇疯緭鍏ユ暟閲�',
- precision: 2,
- },
- rules: 'required',
- dependencies: {
- triggerFields: ['quantityMax'],
- componentProps: (values) => ({
- class: '!w-full',
- max: values.quantityMax,
- min: 0,
- placeholder: '璇疯緭鍏ユ暟閲�',
- precision: 2,
- }),
- },
- },
- {
- fieldName: 'warehouseId',
- label: '鍑哄簱浠撳簱',
- component: markRaw(WmWarehouseSelect),
- componentProps: {
- disabled: true,
- },
- },
- {
- fieldName: 'locationId',
- label: '搴撳尯',
- component: markRaw(WmWarehouseLocationSelect),
- componentProps: {
- disabled: true,
- },
- dependencies: {
- triggerFields: ['warehouseId'],
- componentProps: (values) => ({
- disabled: true,
- warehouseId: values.warehouseId,
- }),
- },
- },
- {
- fieldName: 'areaId',
- label: '搴撲綅',
- component: markRaw(WmWarehouseAreaSelect),
- componentProps: {
- disabled: true,
- },
- dependencies: {
- triggerFields: ['locationId'],
- componentProps: (values) => ({
- disabled: true,
- locationId: values.locationId,
- }),
- },
- },
- {
- fieldName: 'batchCode',
- label: '鎵规鍙�',
- component: 'Input',
- componentProps: {
- disabled: true,
- },
- },
- ];
-}
diff --git a/src/views/productsales/index.vue b/src/views/productsales/index.vue
deleted file mode 100644
index 1b0dc47..0000000
--- a/src/views/productsales/index.vue
+++ /dev/null
@@ -1,215 +0,0 @@
-<script lang="ts" setup>
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmProductSalesApi } from '#/api/mes/wm/productsales';
-
-import { Page, useVbenModal } from '@vben/common-ui';
-import { MesWmProductSalesStatusEnum } from '@vben/constants';
-import { downloadFileFromBlobPart } from '@vben/utils';
-
-import { Button, message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import {
- cancelProductSales,
- deleteProductSales,
- exportProductSales,
- getProductSalesPage,
-} from '#/api/mes/wm/productsales';
-import { $t } from '#/locales';
-
-import { useGridColumns, useGridFormSchema } from './data';
-import Form from './modules/form.vue';
-
-const [FormModal, formModalApi] = useVbenModal({
- connectedComponent: Form,
- destroyOnClose: true,
-});
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- gridApi.query();
-}
-
-/** 鍒涘缓閿�鍞嚭搴撳崟 */
-function handleCreate() {
- formModalApi.setData({ formType: 'create' }).open();
-}
-
-/** 鏌ョ湅閿�鍞嚭搴撳崟 */
-function handleDetail(row: MesWmProductSalesApi.ProductSales) {
- formModalApi.setData({ formType: 'detail', id: row.id }).open();
-}
-
-/** 缂栬緫閿�鍞嚭搴撳崟 */
-function handleEdit(row: MesWmProductSalesApi.ProductSales) {
- formModalApi.setData({ formType: 'update', id: row.id }).open();
-}
-
-/** 鎵ц鎷h揣 */
-function handleStock(row: MesWmProductSalesApi.ProductSales) {
- formModalApi.setData({ formType: 'stock', id: row.id }).open();
-}
-
-/** 濉啓杩愬崟 */
-function handleShipping(row: MesWmProductSalesApi.ProductSales) {
- formModalApi.setData({ formType: 'shipping', id: row.id }).open();
-}
-
-/** 鎵ц鍑哄簱 */
-function handleFinish(row: MesWmProductSalesApi.ProductSales) {
- formModalApi.setData({ formType: 'finish', id: row.id }).open();
-}
-
-/** 鍒犻櫎閿�鍞嚭搴撳崟 */
-async function handleDelete(row: MesWmProductSalesApi.ProductSales) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.code]),
- duration: 0,
- });
- try {
- await deleteProductSales(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.code]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-/** 鍙栨秷閿�鍞嚭搴撳崟 */
-async function handleCancel(row: MesWmProductSalesApi.ProductSales) {
- await cancelProductSales(row.id!);
- message.success('鍙栨秷鎴愬姛');
- handleRefresh();
-}
-
-/** 瀵煎嚭琛ㄦ牸 */
-async function handleExport() {
- const data = await exportProductSales(await gridApi.formApi.getValues());
- downloadFileFromBlobPart({ fileName: '閿�鍞嚭搴撳崟.xls', source: data });
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- formOptions: {
- schema: useGridFormSchema(),
- },
- gridOptions: {
- columns: useGridColumns(),
- height: 'auto',
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }, formValues) => {
- return await getProductSalesPage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- ...formValues,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- search: true,
- },
- } as VxeTableGridOptions<MesWmProductSalesApi.ProductSales>,
-});
-</script>
-
-<template>
- <Page auto-content-height><FormModal @success="handleRefresh" />
-
- <Grid table-title="閿�鍞嚭搴撳崟鍒楄〃">
- <template #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: $t('ui.actionTitle.create', ['閿�鍞嚭搴撳崟']),
- type: 'primary',
- icon: ACTION_ICON.ADD,
- auth: ['mes:wm-product-sales:create'],
- onClick: handleCreate,
- },
- {
- label: $t('ui.actionTitle.export'),
- type: 'primary',
- icon: ACTION_ICON.DOWNLOAD,
- auth: ['mes:wm-product-sales:export'],
- onClick: handleExport,
- },
- ]"
- />
- </template>
- <template #code="{ row }">
- <Button type="link" @click="handleDetail(row)">
- {{ row.code }}
- </Button>
- </template>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- auth: ['mes:wm-product-sales:update'],
- ifShow: row.status === MesWmProductSalesStatusEnum.PREPARE,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- auth: ['mes:wm-product-sales:delete'],
- ifShow: row.status === MesWmProductSalesStatusEnum.PREPARE,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.code]),
- confirm: handleDelete.bind(null, row),
- },
- },
- {
- label: '鎷h揣',
- type: 'link',
- auth: ['mes:wm-product-sales:stock'],
- ifShow: row.status === MesWmProductSalesStatusEnum.APPROVING,
- onClick: handleStock.bind(null, row),
- },
- {
- label: '濉啓杩愬崟',
- type: 'link',
- auth: ['mes:wm-product-sales:shipping'],
- ifShow: row.status === MesWmProductSalesStatusEnum.SHIPPING,
- onClick: handleShipping.bind(null, row),
- },
- {
- label: '鎵ц鍑哄簱',
- type: 'link',
- auth: ['mes:wm-product-sales:finish'],
- ifShow: row.status === MesWmProductSalesStatusEnum.APPROVED,
- onClick: handleFinish.bind(null, row),
- },
- {
- label: '鍙栨秷',
- type: 'link',
- danger: true,
- auth: ['mes:wm-product-sales:cancel'],
- ifShow:
- row.status === MesWmProductSalesStatusEnum.CONFIRMED ||
- row.status === MesWmProductSalesStatusEnum.APPROVING ||
- row.status === MesWmProductSalesStatusEnum.SHIPPING ||
- row.status === MesWmProductSalesStatusEnum.APPROVED,
- popConfirm: {
- title: '纭鍙栨秷璇ラ攢鍞嚭搴撳崟锛熷彇娑堝悗涓嶅彲鎭㈠銆�',
- confirm: handleCancel.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </Page>
-</template>
diff --git a/src/views/productsales/modules/detail-form.vue b/src/views/productsales/modules/detail-form.vue
deleted file mode 100644
index 122c318..0000000
--- a/src/views/productsales/modules/detail-form.vue
+++ /dev/null
@@ -1,110 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmProductSalesDetailApi } from '#/api/mes/wm/productsales/detail';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createProductSalesDetail,
- getProductSalesDetail,
- updateProductSalesDetail,
-} from '#/api/mes/wm/productsales/detail';
-import { $t } from '#/locales';
-
-import { useDetailFormSchema } from '../data';
-
-const emit = defineEmits<{ success: [lineId: number] }>();
-const formData = ref<MesWmProductSalesDetailApi.ProductSalesDetail>();
-const salesId = ref<number>(); // 鎵�灞炲嚭搴撳崟缂栧彿
-const lineId = ref<number>(); // 鎵�灞炲嚭搴撳崟琛岀紪鍙�
-
-const getTitle = computed(() => {
- return formData.value?.id
- ? $t('ui.actionTitle.edit', ['鎷h揣鏄庣粏'])
- : $t('ui.actionTitle.create', ['鎷h揣鏄庣粏']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 90,
- },
- layout: 'horizontal',
- schema: useDetailFormSchema(),
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data =
- (await formApi.getValues()) as MesWmProductSalesDetailApi.ProductSalesDetail;
- data.salesId = salesId.value;
- data.lineId = lineId.value;
- try {
- await (formData.value?.id
- ? updateProductSalesDetail({ ...data, id: formData.value.id })
- : createProductSalesDetail(data));
- // 鍏抽棴骞舵彁绀�
- await modalApi.close();
- emit('success', lineId.value!);
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- return;
- }
- formApi.setState({ schema: useDetailFormSchema(formApi) });
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{
- batchId?: number;
- detailId?: number;
- itemId?: number;
- lineId: number;
- salesId: number;
- }>();
- salesId.value = data.salesId;
- lineId.value = data.lineId;
- if (data.detailId) {
- modalApi.lock();
- try {
- formData.value = await getProductSalesDetail(data.detailId);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- } else {
- if (data.itemId) {
- await formApi.setFieldValue('itemId', data.itemId);
- }
- if (data.batchId) {
- await formApi.setFieldValue('batchId', data.batchId);
- }
- }
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- </Modal>
-</template>
diff --git a/src/views/productsales/modules/detail-list.vue b/src/views/productsales/modules/detail-list.vue
deleted file mode 100644
index 8a153bd..0000000
--- a/src/views/productsales/modules/detail-list.vue
+++ /dev/null
@@ -1,105 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmProductSalesDetailApi } from '#/api/mes/wm/productsales/detail';
-
-import { computed, watch } from 'vue';
-
-import { message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import { deleteProductSalesDetail } from '#/api/mes/wm/productsales/detail';
-import { $t } from '#/locales';
-
-import { useDetailGridColumns } from '../data';
-
-const props = defineProps<{
- details: MesWmProductSalesDetailApi.ProductSalesDetail[];
- formType: FormType;
-}>();
-
-const emit = defineEmits<{
- edit: [detailId: number];
- refresh: [];
-}>();
-
-const isStock = computed(() => props.formType === 'stock'); // 鏄惁涓烘嫞璐фā寮�
-
-/** 缂栬緫鎷h揣鏄庣粏 */
-function handleEdit(row: MesWmProductSalesDetailApi.ProductSalesDetail) {
- emit('edit', row.id!);
-}
-
-/** 鍒犻櫎鎷h揣鏄庣粏 */
-async function handleDelete(
- row: MesWmProductSalesDetailApi.ProductSalesDetail,
-) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.warehouseName]),
- duration: 0,
- });
- try {
- await deleteProductSalesDetail(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.warehouseName]));
- emit('refresh');
- } finally {
- hideLoading();
- }
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- gridOptions: {
- border: true,
- columns: useDetailGridColumns(isStock.value),
- data: props.details,
- pagerConfig: {
- enabled: false,
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- size: 'small',
- toolbarConfig: {
- enabled: false,
- },
- } as VxeTableGridOptions<MesWmProductSalesDetailApi.ProductSalesDetail>,
-});
-
-watch(
- () => props.details,
- (details) => gridApi.setGridOptions({ data: details }),
-);
-</script>
-
-<template>
- <div class="px-4 py-2">
- <Grid>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [
- row.warehouseName,
- ]),
- confirm: handleDelete.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </div>
-</template>
diff --git a/src/views/productsales/modules/form.vue b/src/views/productsales/modules/form.vue
deleted file mode 100644
index f6ba967..0000000
--- a/src/views/productsales/modules/form.vue
+++ /dev/null
@@ -1,270 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { MesWmProductSalesApi } from '#/api/mes/wm/productsales';
-
-import { computed, ref } from 'vue';
-
-import { confirm, useVbenModal } from '@vben/common-ui';
-import { MesWmProductSalesStatusEnum } from '@vben/constants';
-
-import { Button, Divider, message, Popconfirm } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- checkProductSalesQuantity,
- createProductSales,
- finishProductSales,
- getProductSales,
- shippingProductSales,
- stockProductSales,
- submitProductSales,
- updateProductSales,
-} from '#/api/mes/wm/productsales';
-import { $t } from '#/locales';
-
-import { useFormSchema } from '../data';
-import LineList from './line-list.vue';
-
-const emit = defineEmits(['success']);
-const formType = ref<FormType>('create');
-const formData = ref<MesWmProductSalesApi.ProductSales>();
-const originalSnapshot = ref(''); // 琛ㄥ崟鍘熷鏁版嵁蹇収锛岀敤浜庢彁浜ゆ椂璺宠繃鏈彉鏇寸殑淇濆瓨璇锋眰
-const isEditable = computed(() =>
- // 鏄惁涓虹紪杈戞ā寮忥紙鍙繚瀛橈級
- ['create', 'update'].includes(formType.value),
-);
-const isStock = computed(() => formType.value === 'stock'); // 鏄惁涓烘嫞璐фā寮�
-const isShipping = computed(() => formType.value === 'shipping'); // 鏄惁涓哄~鍐欒繍鍗曟ā寮�
-const isFinish = computed(() => formType.value === 'finish'); // 鏄惁涓烘墽琛屽嚭搴撴ā寮�
-const canSubmit = computed(
- () =>
- // 鏄惁鍙彁浜�
- formType.value === 'update' &&
- formData.value?.status === MesWmProductSalesStatusEnum.PREPARE,
-);
-const getTitle = computed(() => {
- if (formType.value === 'detail') {
- return $t('ui.actionTitle.view', ['閿�鍞嚭搴撳崟']);
- }
- if (formType.value === 'stock') {
- return '鎵ц鎷h揣';
- }
- if (formType.value === 'shipping') {
- return '濉啓杩愬崟';
- }
- if (formType.value === 'finish') {
- return '鎵ц鍑哄簱';
- }
- return formType.value === 'update'
- ? $t('ui.actionTitle.edit', ['閿�鍞嚭搴撳崟'])
- : $t('ui.actionTitle.create', ['閿�鍞嚭搴撳崟']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 110,
- },
- layout: 'horizontal',
- schema: [],
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-/** 鎻愪氦鍑哄簱鍗曪細琛ㄥ崟鏈変慨鏀规椂鍏堜繚瀛橈紝鍐嶈皟鐢ㄦ彁浜ゆ帴鍙� */
-async function handleSubmit() {
- const { valid } = await formApi.validate();
- if (!valid || !formData.value?.id) {
- return;
- }
- modalApi.lock();
- try {
- const current = JSON.stringify(await formApi.getValues());
- if (current !== originalSnapshot.value) {
- const data =
- (await formApi.getValues()) as MesWmProductSalesApi.ProductSales;
- await updateProductSales({ ...formData.value, ...data });
- originalSnapshot.value = current;
- }
- await submitProductSales(formData.value.id);
- message.success('鎻愪氦鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-/** 鎵ц鎷h揣锛氬嚭搴撴暟閲忎笌鎷h揣鏁伴噺涓嶄竴鑷存椂浜屾纭 */
-async function handleStock() {
- if (!formData.value?.id) {
- return;
- }
- const quantityMatch = await checkProductSalesQuantity(formData.value.id);
- if (!quantityMatch) {
- try {
- await confirm('鍑哄簱鏁伴噺涓庢嫞璐ф暟閲忎笉涓�鑷达紝纭鎵ц鎷h揣锛�');
- } catch {
- return;
- }
- }
- modalApi.lock();
- try {
- await stockProductSales(formData.value.id);
- message.success('鎷h揣鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-/** 濉啓杩愬崟 */
-async function handleShipping() {
- if (!formData.value?.id) {
- return;
- }
- const values =
- (await formApi.getValues()) as MesWmProductSalesApi.ProductSales;
- modalApi.lock();
- try {
- await shippingProductSales({
- carrier: values.carrier,
- id: formData.value.id,
- shippingNumber: values.shippingNumber,
- });
- message.success('杩愬崟淇℃伅濉啓鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-/** 鎵ц鍑哄簱 */
-async function handleFinish() {
- if (!formData.value?.id) {
- return;
- }
- modalApi.lock();
- try {
- await finishProductSales(formData.value.id);
- message.success('鍑哄簱鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- if (!isEditable.value) {
- await modalApi.close();
- return;
- }
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data =
- (await formApi.getValues()) as MesWmProductSalesApi.ProductSales;
- try {
- if (formData.value?.id) {
- await updateProductSales({ ...formData.value, ...data });
- formData.value = { ...formData.value, ...data };
- } else {
- const id = await createProductSales(data);
- formData.value = {
- ...data,
- id,
- status: MesWmProductSalesStatusEnum.PREPARE,
- };
- await formApi.setFieldValue('id', id);
- await formApi.setFieldValue('status', formData.value.status);
- formType.value = 'update';
- }
- originalSnapshot.value = JSON.stringify(await formApi.getValues());
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- originalSnapshot.value = '';
- return;
- }
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{ formType: FormType; id?: number }>();
- formType.value = data.formType;
- formApi.setState({ schema: useFormSchema(formType.value, formApi) });
- formApi.setDisabled(false);
- modalApi.setState({ showConfirmButton: isEditable.value });
- if (data?.id) {
- modalApi.lock();
- try {
- formData.value = await getProductSales(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- }
- originalSnapshot.value = JSON.stringify(await formApi.getValues());
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- <!-- 闈炴柊寤烘ā寮忓睍绀虹墿鏂欎俊鎭� -->
- <template v-if="formData?.id">
- <Divider>鐗╂枡淇℃伅</Divider>
- <div class="mx-4">
- <LineList
- :form-type="formType"
- :notice-id="formData.noticeId"
- :sales-id="formData.id"
- />
- </div>
- </template>
- <template #prepend-footer>
- <div class="flex flex-auto items-center gap-2">
- <Popconfirm
- v-if="canSubmit"
- title="纭鎻愪氦璇ラ攢鍞嚭搴撳崟锛熴�愭彁浜ゅ悗灏嗕笉鑳戒慨鏀广��"
- @confirm="handleSubmit"
- >
- <Button type="primary">鎻愪氦</Button>
- </Popconfirm>
- <Button v-if="isStock" type="primary" @click="handleStock">
- 鎵ц鎷h揣
- </Button>
- <Popconfirm
- v-if="isShipping"
- title="纭鎻愪氦杩愬崟淇℃伅锛�"
- @confirm="handleShipping"
- >
- <Button type="primary">纭濉啓</Button>
- </Popconfirm>
- <Popconfirm
- v-if="isFinish"
- title="纭鎵ц鍑哄簱锛熸墽琛屽悗灏嗘墸鍑忓簱瀛樸��"
- @confirm="handleFinish"
- >
- <Button type="primary">纭鍑哄簱</Button>
- </Popconfirm>
- </div>
- </template>
- </Modal>
-</template>
diff --git a/src/views/productsales/modules/line-form.vue b/src/views/productsales/modules/line-form.vue
deleted file mode 100644
index d8470da..0000000
--- a/src/views/productsales/modules/line-form.vue
+++ /dev/null
@@ -1,104 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmProductSalesLineApi } from '#/api/mes/wm/productsales/line';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createProductSalesLine,
- getProductSalesLine,
- updateProductSalesLine,
-} from '#/api/mes/wm/productsales/line';
-import { $t } from '#/locales';
-
-import { useLineFormSchema } from '../data';
-
-const emit = defineEmits(['success']);
-const formData = ref<MesWmProductSalesLineApi.ProductSalesLine>();
-const salesId = ref<number>(); // 鎵�灞炲嚭搴撳崟缂栧彿
-const noticeId = ref<number>(); // 鎵�灞炲彂璐ч�氱煡鍗曠紪鍙�
-
-const getTitle = computed(() => {
- return formData.value?.id
- ? $t('ui.actionTitle.edit', ['閿�鍞嚭搴撳崟琛�'])
- : $t('ui.actionTitle.create', ['閿�鍞嚭搴撳崟琛�']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 110,
- },
- layout: 'horizontal',
- schema: [],
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data =
- (await formApi.getValues()) as MesWmProductSalesLineApi.ProductSalesLine;
- data.salesId = salesId.value;
- try {
- await (formData.value?.id
- ? updateProductSalesLine({ ...data, id: formData.value.id })
- : createProductSalesLine(data));
- // 鍏抽棴骞舵彁绀�
- await modalApi.close();
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- return;
- }
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{
- id?: number;
- noticeId?: number;
- salesId: number;
- }>();
- salesId.value = data.salesId;
- noticeId.value = data.noticeId;
- formApi.setState({ schema: useLineFormSchema(!!data.noticeId, formApi) });
- if (data.noticeId) {
- await formApi.setFieldValue('noticeId', data.noticeId);
- }
- if (!data.id) {
- return;
- }
- modalApi.lock();
- try {
- formData.value = await getProductSalesLine(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues({ ...formData.value, noticeId: noticeId.value });
- } finally {
- modalApi.unlock();
- }
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- </Modal>
-</template>
diff --git a/src/views/productsales/modules/line-list.vue b/src/views/productsales/modules/line-list.vue
deleted file mode 100644
index 0cdc204..0000000
--- a/src/views/productsales/modules/line-list.vue
+++ /dev/null
@@ -1,236 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmProductSalesDetailApi } from '#/api/mes/wm/productsales/detail';
-import type { MesWmProductSalesLineApi } from '#/api/mes/wm/productsales/line';
-
-import { computed, reactive } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import { getProductSalesDetailListByLineId } from '#/api/mes/wm/productsales/detail';
-import {
- deleteProductSalesLine,
- getProductSalesLinePage,
-} from '#/api/mes/wm/productsales/line';
-import { $t } from '#/locales';
-
-import { useLineGridColumns } from '../data';
-import DetailForm from './detail-form.vue';
-import DetailList from './detail-list.vue';
-import LineForm from './line-form.vue';
-
-const props = defineProps<{
- formType: FormType;
- noticeId?: number;
- salesId: number;
-}>();
-
-const isEditable = computed(() =>
- // 鏄惁鍙紪杈戞槑缁嗚
- ['create', 'update'].includes(props.formType),
-);
-const isStock = computed(() => props.formType === 'stock'); // 鏄惁涓烘嫞璐фā寮�
-const detailMap = reactive<
- Record<number, MesWmProductSalesDetailApi.ProductSalesDetail[]>
->({}); // 宸插睍寮�琛岀殑鎷h揣鏄庣粏缂撳瓨
-
-const [LineFormModal, lineFormModalApi] = useVbenModal({
- connectedComponent: LineForm,
- destroyOnClose: true,
-});
-
-const [DetailFormModal, detailFormModalApi] = useVbenModal({
- connectedComponent: DetailForm,
- destroyOnClose: true,
-});
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- for (const id of Object.keys(detailMap)) {
- delete detailMap[Number(id)];
- }
- gridApi.query();
-}
-
-/** 娣诲姞鐗╂枡 */
-function handleCreate() {
- lineFormModalApi
- .setData({ noticeId: props.noticeId, salesId: props.salesId })
- .open();
-}
-
-/** 缂栬緫鐗╂枡 */
-function handleEdit(row: MesWmProductSalesLineApi.ProductSalesLine) {
- lineFormModalApi
- .setData({ id: row.id, noticeId: props.noticeId, salesId: props.salesId })
- .open();
-}
-
-/** 鍒犻櫎鐗╂枡 */
-async function handleDelete(row: MesWmProductSalesLineApi.ProductSalesLine) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.itemName]),
- duration: 0,
- });
- try {
- await deleteProductSalesLine(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.itemName]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-/** 鎷h揣锛氱洿鎺ユ墦寮�鏄庣粏鍒涘缓琛ㄥ崟 */
-function handlePicking(row: MesWmProductSalesLineApi.ProductSalesLine) {
- openDetailForm(row.id!, row.itemId, row.batchId);
-}
-
-/** 鎵撳紑鎷h揣鏄庣粏琛ㄥ崟 */
-function openDetailForm(
- lineId: number,
- itemId?: number,
- batchId?: number,
- detailId?: number,
-) {
- detailFormModalApi
- .setData({ batchId, detailId, itemId, lineId, salesId: props.salesId })
- .open();
-}
-
-/** 鑾峰彇宸插睍寮�琛岀殑鎷h揣鏄庣粏 */
-function getExpandedDetails(row: MesWmProductSalesLineApi.ProductSalesLine) {
- return detailMap[row.id!] || [];
-}
-
-/** 鍔犺浇鎸囧畾琛岀殑鎷h揣鏄庣粏 */
-async function loadLineDetails(lineId: number) {
- detailMap[lineId] = await getProductSalesDetailListByLineId(lineId);
-}
-
-/** 灞曞紑琛屾椂鎳掑姞杞芥嫞璐ф槑缁� */
-async function handleExpandChange(
- row: MesWmProductSalesLineApi.ProductSalesLine,
- expanded: boolean,
-) {
- if (!expanded) {
- return;
- }
- await loadLineDetails(row.id!);
-}
-
-/** 鏄庣粏琛ㄥ崟鎻愪氦鎴愬姛鍚庯紝鍒锋柊瀵瑰簲琛屽凡灞曞紑鐨勬槑缁� */
-async function handleDetailSuccess(lineId: number) {
- await loadLineDetails(lineId);
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- gridOptions: {
- columns: useLineGridColumns(isEditable.value, isStock.value),
- expandConfig: {
- padding: true,
- },
- height: 400,
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }) => {
- if (!props.salesId) {
- return { list: [], total: 0 };
- }
- return await getProductSalesLinePage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- salesId: props.salesId,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- },
- } as VxeTableGridOptions<MesWmProductSalesLineApi.ProductSalesLine>,
- gridEvents: {
- toggleRowExpand: ({
- expanded,
- row,
- }: {
- expanded: boolean;
- row: MesWmProductSalesLineApi.ProductSalesLine;
- }) => {
- handleExpandChange(row, expanded);
- },
- },
-});
-</script>
-
-<template>
- <div>
- <LineFormModal @success="handleRefresh" />
- <DetailFormModal @success="handleDetailSuccess" />
- <Grid table-title="鐗╂枡淇℃伅">
- <template v-if="isEditable" #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: '娣诲姞鐗╂枡',
- type: 'primary',
- icon: ACTION_ICON.ADD,
- onClick: handleCreate,
- },
- ]"
- />
- </template>
- <template #detail="{ row }">
- <DetailList
- :details="getExpandedDetails(row)"
- :form-type="formType"
- @edit="
- (detailId) =>
- openDetailForm(row.id!, row.itemId, row.batchId, detailId)
- "
- @refresh="loadLineDetails(row.id!)"
- />
- </template>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- ifShow: isEditable,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- ifShow: isEditable,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.itemName]),
- confirm: handleDelete.bind(null, row),
- },
- },
- {
- label: '鎷h揣',
- type: 'link',
- ifShow: isStock,
- onClick: handlePicking.bind(null, row),
- },
- ]"
- />
- </template>
- </Grid>
- </div>
-</template>
diff --git a/src/views/returnissue/data.ts b/src/views/returnissue/data.ts
deleted file mode 100644
index d25a934..0000000
--- a/src/views/returnissue/data.ts
+++ /dev/null
@@ -1,567 +0,0 @@
-锘縤mport type { VbenFormApi, VbenFormSchema } from '#/adapter/form';
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmMaterialStockApi } from '#/api/mes/wm/materialstock';
-import type { MesWmReturnIssueApi } from '#/api/mes/wm/returnissue';
-import type { MesWmReturnIssueDetailApi } from '#/api/mes/wm/returnissue/detail';
-import type { MesWmReturnIssueLineApi } from '#/api/mes/wm/returnissue/line';
-
-import { h, markRaw } from 'vue';
-
-import {
- DICT_TYPE,
- MesAutoCodeRuleCode,
- MesProWorkOrderStatusEnum,
-} from '@vben/constants';
-import { getDictOptions } from '@vben/hooks';
-
-import { Button } from 'ant-design-vue';
-
-import { z } from '#/adapter/form';
-import { generateAutoCode } from '#/api/mes/md/autocode/record';
-import { MdItemSelect } from '#/views/mes/md/item/components';
-import { MdWorkstationSelect } from '#/views/mes/md/workstation/components';
-import { ProWorkOrderSelect } from '#/views/mes/pro/workorder/components';
-import { WmMaterialStockSelect } from '#/views/wls/materialstock/components';
-import {
- WmWarehouseAreaSelect,
- WmWarehouseLocationSelect,
- WmWarehouseSelect,
-} from '#/views/wls/warehouse/components';
-
-/** 琛ㄥ崟绫诲瀷 */
-export type FormType = 'create' | 'detail' | 'finish' | 'stock' | 'update';
-
-/** 琛ㄥ崟澶撮儴鏄惁鍙锛堜笂鏋躲�佽鎯呫�佹墽琛岄��鏂欐�侊級 */
-function isHeaderReadonly(formType: FormType): boolean {
- return formType === 'detail' || formType === 'finish' || formType === 'stock';
-}
-
-/** 鏂板/淇敼鐨勮〃鍗� */
-export function useFormSchema(
- formType: FormType,
- formApi?: VbenFormApi,
-): VbenFormSchema[] {
- return [
- {
- fieldName: 'id',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'status',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'code',
- label: '閫�鏂欏崟缂栧彿',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ラ��鏂欏崟缂栧彿',
- },
- rules: 'required',
- suffix: isHeaderReadonly(formType)
- ? undefined
- : () =>
- h(
- Button,
- {
- type: 'default',
- onClick: async () => {
- const code = await generateAutoCode(
- MesAutoCodeRuleCode.WM_RETURN_ISSUE_CODE,
- );
- await formApi?.setFieldValue('code', code);
- },
- },
- { default: () => '鐢熸垚' },
- ),
- },
- {
- fieldName: 'name',
- label: '閫�鏂欏崟鍚嶇О',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ラ��鏂欏崟鍚嶇О',
- },
- rules: 'required',
- },
- {
- fieldName: 'type',
- label: '閫�鏂欑被鍨�',
- component: 'Select',
- componentProps: {
- allowClear: true,
- options: getDictOptions(DICT_TYPE.MES_WM_RETURN_ISSUE_TYPE, 'number'),
- placeholder: '璇烽�夋嫨閫�鏂欑被鍨�',
- },
- rules: 'required',
- },
- {
- fieldName: 'workOrderId',
- label: '鐢熶骇璁㈠崟',
- component: markRaw(ProWorkOrderSelect),
- componentProps: {
- status: MesProWorkOrderStatusEnum.CONFIRMED,
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'workstationId',
- label: '宸ヤ綔绔�',
- component: markRaw(MdWorkstationSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨宸ヤ綔绔�',
- },
- },
- {
- fieldName: 'returnDate',
- label: '閫�鏂欐棩鏈�',
- component: 'DatePicker',
- componentProps: {
- class: '!w-full',
- format: 'YYYY-MM-DD HH:mm:ss',
- placeholder: '璇烽�夋嫨閫�鏂欐棩鏈�',
- showTime: true,
- valueFormat: 'x',
- },
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勬悳绱㈣〃鍗� */
-export function useGridFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'code',
- label: '閫�鏂欏崟缂栧彿',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ラ��鏂欏崟缂栧彿',
- },
- },
- {
- fieldName: 'name',
- label: '閫�鏂欏崟鍚嶇О',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ラ��鏂欏崟鍚嶇О',
- },
- },
- {
- fieldName: 'workOrderId',
- label: '鐢熶骇璁㈠崟',
- component: markRaw(ProWorkOrderSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨鐢熶骇璁㈠崟',
- },
- },
- {
- fieldName: 'type',
- label: '閫�鏂欑被鍨�',
- component: 'Select',
- componentProps: {
- allowClear: true,
- options: getDictOptions(DICT_TYPE.MES_WM_RETURN_ISSUE_TYPE, 'number'),
- placeholder: '璇烽�夋嫨閫�鏂欑被鍨�',
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勫瓧娈� */
-export function useGridColumns(): VxeTableGridOptions<MesWmReturnIssueApi.ReturnIssue>['columns'] {
- return [
- {
- field: 'code',
- title: '閫�鏂欏崟缂栧彿',
- minWidth: 160,
- slots: { default: 'code' },
- },
- {
- field: 'name',
- title: '閫�鏂欏崟鍚嶇О',
- minWidth: 150,
- },
- {
- field: 'type',
- title: '閫�鏂欑被鍨�',
- minWidth: 110,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_RETURN_ISSUE_TYPE },
- },
- },
- {
- field: 'workOrderCode',
- title: '鐢熶骇璁㈠崟',
- minWidth: 140,
- },
- {
- field: 'workstationName',
- title: '宸ヤ綔绔�',
- minWidth: 120,
- },
- {
- field: 'returnDate',
- title: '閫�鏂欐棩鏈�',
- width: 180,
- formatter: 'formatDateTime',
- },
- {
- field: 'status',
- title: '鍗曟嵁鐘舵��',
- minWidth: 110,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_RETURN_ISSUE_STATUS },
- },
- },
- {
- title: '鎿嶄綔',
- width: 240,
- fixed: 'right',
- slots: { default: 'actions' },
- },
- ];
-}
-
-/** 閫�鏂欏崟琛屽瓙琛ㄧ殑瀛楁 */
-export function useLineGridColumns(
- editable: boolean,
- stockable: boolean,
-): VxeTableGridOptions<MesWmReturnIssueLineApi.ReturnIssueLine>['columns'] {
- return [
- {
- type: 'expand',
- width: 48,
- slots: { content: 'detail' },
- },
- {
- field: 'itemCode',
- title: '鐗╂枡缂栫爜',
- minWidth: 120,
- },
- {
- field: 'itemName',
- title: '鐗╂枡鍚嶇О',
- minWidth: 140,
- },
- {
- field: 'specification',
- title: '瑙勬牸鍨嬪彿',
- minWidth: 120,
- },
- {
- field: 'unitMeasureName',
- title: '鍗曚綅',
- width: 80,
- },
- {
- field: 'quantity',
- title: '閫�鏂欐暟閲�',
- width: 100,
- },
- {
- field: 'batchCode',
- title: '鎵规鍙�',
- minWidth: 120,
- },
- {
- field: 'rqcCheckFlag',
- title: '鏄惁妫�娴�',
- width: 100,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.INFRA_BOOLEAN_STRING },
- },
- },
- {
- field: 'qualityStatus',
- title: '璐ㄩ噺鐘舵��',
- width: 100,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_QUALITY_STATUS },
- },
- },
- ...(editable || stockable
- ? [
- {
- title: '鎿嶄綔',
- width: 200,
- fixed: 'right',
- slots: { default: 'actions' },
- } as const,
- ]
- : []),
- ];
-}
-
-/** 閫�鏂欏崟琛屾柊澧�/淇敼鐨勮〃鍗� */
-export function useLineFormSchema(formApi?: VbenFormApi): VbenFormSchema[] {
- return [
- {
- fieldName: 'materialStockId',
- label: '搴撳瓨璁板綍',
- component: markRaw(WmMaterialStockSelect),
- componentProps: {
- // 閫夋嫨搴撳瓨璁板綍鍚庯紝鑷姩鍥炲~鐗╂枡/鎵规/鏁伴噺
- onChange: async (stock?: MesWmMaterialStockApi.MaterialStock) => {
- await formApi?.setValues({
- batchCode: stock?.batchCode,
- batchId: stock?.batchId,
- itemId: stock?.itemId,
- quantity: stock?.quantity,
- quantityMax: stock?.quantity,
- });
- },
- virtualFilter: 'only',
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'quantityMax',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'quantity',
- label: '閫�鏂欐暟閲�',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0,
- placeholder: '璇疯緭鍏ラ��鏂欐暟閲�',
- precision: 2,
- },
- rules: 'required',
- dependencies: {
- triggerFields: ['quantityMax'],
- componentProps: (values) => ({
- class: '!w-full',
- max: values.quantityMax,
- min: 0,
- placeholder: '璇疯緭鍏ラ��鏂欐暟閲�',
- precision: 2,
- }),
- },
- },
- {
- fieldName: 'rqcCheckFlag',
- label: '闇�瑕佽川妫�',
- component: 'Switch',
- rules: z.boolean().default(false),
- },
- {
- fieldName: 'itemId',
- label: '鐗╂枡',
- component: markRaw(MdItemSelect),
- componentProps: {
- disabled: true,
- },
- },
- {
- fieldName: 'batchCode',
- label: '鎵规鍙�',
- component: 'Input',
- componentProps: {
- disabled: true,
- placeholder: '閫夋嫨搴撳瓨鍚庤嚜鍔ㄥ甫鍑�',
- },
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
-
-/** 涓婃灦鏄庣粏瀛愯〃鐨勫瓧娈� */
-export function useDetailGridColumns(
- stockable: boolean,
-): VxeTableGridOptions<MesWmReturnIssueDetailApi.ReturnIssueDetail>['columns'] {
- return [
- {
- field: 'batchCode',
- title: '鎵规鍙�',
- minWidth: 120,
- },
- {
- field: 'warehouseName',
- title: '浠撳簱鍚嶇О',
- minWidth: 100,
- },
- {
- field: 'locationName',
- title: '搴撳尯鍚嶇О',
- minWidth: 100,
- },
- {
- field: 'areaName',
- title: '搴撲綅鍚嶇О',
- minWidth: 100,
- },
- {
- field: 'quantity',
- title: '鏁伴噺',
- width: 100,
- },
- ...(stockable
- ? [
- {
- title: '鎿嶄綔',
- width: 120,
- fixed: 'right',
- slots: { default: 'actions' },
- } as const,
- ]
- : []),
- ];
-}
-
-/** 涓婃灦鏄庣粏鏂板/淇敼鐨勮〃鍗� */
-export function useDetailFormSchema(formApi?: VbenFormApi): VbenFormSchema[] {
- return [
- {
- fieldName: 'quantityMax',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'itemId',
- label: '鐗╂枡',
- component: markRaw(MdItemSelect),
- componentProps: {
- disabled: true,
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'materialStockId',
- label: '搴撳瓨璁板綍',
- component: markRaw(WmMaterialStockSelect),
- componentProps: {
- // 閫夋嫨搴撳瓨璁板綍鍚庯紝鑷姩鍥炲~浠撳簱/搴撳尯/搴撲綅/鎵规/鏁伴噺
- onChange: async (stock?: MesWmMaterialStockApi.MaterialStock) => {
- await formApi?.setValues({
- areaId: stock?.areaId,
- batchCode: stock?.batchCode,
- batchId: stock?.batchId,
- locationId: stock?.locationId,
- quantity: stock?.quantity,
- quantityMax: stock?.quantity,
- warehouseId: stock?.warehouseId,
- });
- },
- virtualFilter: 'only',
- },
- rules: 'selectRequired',
- dependencies: {
- triggerFields: ['itemId'],
- componentProps: (values) => ({
- itemId: values.itemId,
- virtualFilter: 'only',
- }),
- },
- },
- {
- fieldName: 'quantity',
- label: '鏁伴噺',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0,
- placeholder: '璇疯緭鍏ユ暟閲�',
- precision: 2,
- },
- rules: 'required',
- dependencies: {
- triggerFields: ['quantityMax'],
- componentProps: (values) => ({
- class: '!w-full',
- max: values.quantityMax,
- min: 0,
- placeholder: '璇疯緭鍏ユ暟閲�',
- precision: 2,
- }),
- },
- },
- {
- fieldName: 'warehouseId',
- label: '鍏ュ簱浠撳簱',
- component: markRaw(WmWarehouseSelect),
- componentProps: {
- disabled: true,
- },
- },
- {
- fieldName: 'locationId',
- label: '搴撳尯',
- component: markRaw(WmWarehouseLocationSelect),
- componentProps: {
- disabled: true,
- },
- dependencies: {
- triggerFields: ['warehouseId'],
- componentProps: (values) => ({
- disabled: true,
- warehouseId: values.warehouseId,
- }),
- },
- },
- {
- fieldName: 'areaId',
- label: '搴撲綅',
- component: markRaw(WmWarehouseAreaSelect),
- componentProps: {
- disabled: true,
- },
- dependencies: {
- triggerFields: ['locationId'],
- componentProps: (values) => ({
- disabled: true,
- locationId: values.locationId,
- }),
- },
- },
- {
- fieldName: 'batchCode',
- label: '鎵规鍙�',
- component: 'Input',
- componentProps: {
- disabled: true,
- },
- },
- ];
-}
diff --git a/src/views/returnissue/index.vue b/src/views/returnissue/index.vue
deleted file mode 100644
index 2b0e0b5..0000000
--- a/src/views/returnissue/index.vue
+++ /dev/null
@@ -1,213 +0,0 @@
-<script lang="ts" setup>
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmReturnIssueApi } from '#/api/mes/wm/returnissue';
-
-import { Page, useVbenModal } from '@vben/common-ui';
-import { MesWmReturnIssueStatusEnum } from '@vben/constants';
-import { downloadFileFromBlobPart } from '@vben/utils';
-
-import { Button, message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import {
- cancelReturnIssue,
- deleteReturnIssue,
- exportReturnIssue,
- getReturnIssuePage,
-} from '#/api/mes/wm/returnissue';
-import { $t } from '#/locales';
-
-import { useGridColumns, useGridFormSchema } from './data';
-import Form from './modules/form.vue';
-
-const [FormModal, formModalApi] = useVbenModal({
- connectedComponent: Form,
- destroyOnClose: true,
-});
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- gridApi.query();
-}
-
-/** 鍒涘缓鐢熶骇閫�鏂欏崟 */
-function handleCreate() {
- formModalApi.setData({ formType: 'create' }).open();
-}
-
-/** 鏌ョ湅鐢熶骇閫�鏂欏崟 */
-function handleDetail(row: MesWmReturnIssueApi.ReturnIssue) {
- formModalApi.setData({ formType: 'detail', id: row.id }).open();
-}
-
-/** 缂栬緫鐢熶骇閫�鏂欏崟 */
-function handleEdit(row: MesWmReturnIssueApi.ReturnIssue) {
- formModalApi.setData({ formType: 'update', id: row.id }).open();
-}
-
-/** 鎵ц涓婃灦 */
-function handleStock(row: MesWmReturnIssueApi.ReturnIssue) {
- formModalApi.setData({ formType: 'stock', id: row.id }).open();
-}
-
-/** 鎵ц閫�鏂� */
-function handleFinish(row: MesWmReturnIssueApi.ReturnIssue) {
- formModalApi.setData({ formType: 'finish', id: row.id }).open();
-}
-
-/** 鎻愮ず鍓嶅線璐ㄦ妯″潡 */
-function handleQc() {
- message.info('璇峰墠寰�銆愯川閲忕鐞� - 閫�璐ф楠岋紙RQC锛夈�戜腑杩涜閫�鏂欐楠屾搷浣�');
-}
-
-/** 鍒犻櫎鐢熶骇閫�鏂欏崟 */
-async function handleDelete(row: MesWmReturnIssueApi.ReturnIssue) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.code]),
- duration: 0,
- });
- try {
- await deleteReturnIssue(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.code]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-/** 鍙栨秷鐢熶骇閫�鏂欏崟 */
-async function handleCancel(row: MesWmReturnIssueApi.ReturnIssue) {
- await cancelReturnIssue(row.id!);
- message.success('鍙栨秷鎴愬姛');
- handleRefresh();
-}
-
-/** 瀵煎嚭琛ㄦ牸 */
-async function handleExport() {
- const data = await exportReturnIssue(await gridApi.formApi.getValues());
- downloadFileFromBlobPart({ fileName: '鐢熶骇閫�鏂欏崟.xls', source: data });
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- formOptions: {
- schema: useGridFormSchema(),
- },
- gridOptions: {
- columns: useGridColumns(),
- height: 'auto',
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }, formValues) => {
- return await getReturnIssuePage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- ...formValues,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- search: true,
- },
- } as VxeTableGridOptions<MesWmReturnIssueApi.ReturnIssue>,
-});
-</script>
-
-<template>
- <Page auto-content-height><FormModal @success="handleRefresh" />
-
- <Grid table-title="鐢熶骇閫�鏂欏崟鍒楄〃">
- <template #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: $t('ui.actionTitle.create', ['鐢熶骇閫�鏂欏崟']),
- type: 'primary',
- icon: ACTION_ICON.ADD,
- auth: ['mes:wm-return-issue:create'],
- onClick: handleCreate,
- },
- {
- label: $t('ui.actionTitle.export'),
- type: 'primary',
- icon: ACTION_ICON.DOWNLOAD,
- auth: ['mes:wm-return-issue:export'],
- onClick: handleExport,
- },
- ]"
- />
- </template>
- <template #code="{ row }">
- <Button type="link" @click="handleDetail(row)">
- {{ row.code }}
- </Button>
- </template>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- auth: ['mes:wm-return-issue:update'],
- ifShow: row.status === MesWmReturnIssueStatusEnum.PREPARE,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- auth: ['mes:wm-return-issue:delete'],
- ifShow: row.status === MesWmReturnIssueStatusEnum.PREPARE,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.code]),
- confirm: handleDelete.bind(null, row),
- },
- },
- {
- label: '鎵ц璐ㄦ',
- type: 'link',
- ifShow: row.status === MesWmReturnIssueStatusEnum.CONFIRMED,
- onClick: handleQc,
- },
- {
- label: '鎵ц涓婃灦',
- type: 'link',
- auth: ['mes:wm-return-issue:update'],
- ifShow: row.status === MesWmReturnIssueStatusEnum.APPROVING,
- onClick: handleStock.bind(null, row),
- },
- {
- label: '鎵ц閫�鏂�',
- type: 'link',
- auth: ['mes:wm-return-issue:finish'],
- ifShow: row.status === MesWmReturnIssueStatusEnum.APPROVED,
- onClick: handleFinish.bind(null, row),
- },
- {
- label: '鍙栨秷',
- type: 'link',
- danger: true,
- auth: ['mes:wm-return-issue:update'],
- ifShow:
- row.status === MesWmReturnIssueStatusEnum.CONFIRMED ||
- row.status === MesWmReturnIssueStatusEnum.APPROVING ||
- row.status === MesWmReturnIssueStatusEnum.APPROVED,
- popConfirm: {
- title: '纭鍙栨秷璇ョ敓浜ч��鏂欏崟锛熷彇娑堝悗涓嶅彲鎭㈠銆�',
- confirm: handleCancel.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </Page>
-</template>
diff --git a/src/views/returnissue/modules/detail-form.vue b/src/views/returnissue/modules/detail-form.vue
deleted file mode 100644
index 032c771..0000000
--- a/src/views/returnissue/modules/detail-form.vue
+++ /dev/null
@@ -1,104 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmReturnIssueDetailApi } from '#/api/mes/wm/returnissue/detail';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createReturnIssueDetail,
- getReturnIssueDetail,
- updateReturnIssueDetail,
-} from '#/api/mes/wm/returnissue/detail';
-import { $t } from '#/locales';
-
-import { useDetailFormSchema } from '../data';
-
-const emit = defineEmits<{ success: [lineId: number] }>();
-const formData = ref<MesWmReturnIssueDetailApi.ReturnIssueDetail>();
-const issueId = ref<number>(); // 鎵�灞為��鏂欏崟缂栧彿
-const lineId = ref<number>(); // 鎵�灞為��鏂欏崟琛岀紪鍙�
-
-const getTitle = computed(() => {
- return formData.value?.id
- ? $t('ui.actionTitle.edit', ['涓婃灦鏄庣粏'])
- : $t('ui.actionTitle.create', ['涓婃灦鏄庣粏']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 90,
- },
- layout: 'horizontal',
- schema: useDetailFormSchema(),
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data =
- (await formApi.getValues()) as MesWmReturnIssueDetailApi.ReturnIssueDetail;
- data.issueId = issueId.value;
- data.lineId = lineId.value;
- try {
- await (formData.value?.id
- ? updateReturnIssueDetail({ ...data, id: formData.value.id })
- : createReturnIssueDetail(data));
- // 鍏抽棴骞舵彁绀�
- await modalApi.close();
- emit('success', lineId.value!);
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- return;
- }
- formApi.setState({ schema: useDetailFormSchema(formApi) });
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{
- detailId?: number;
- issueId: number;
- itemId?: number;
- lineId: number;
- }>();
- issueId.value = data.issueId;
- lineId.value = data.lineId;
- if (data.detailId) {
- modalApi.lock();
- try {
- formData.value = await getReturnIssueDetail(data.detailId);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- } else if (data.itemId) {
- await formApi.setFieldValue('itemId', data.itemId);
- }
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- </Modal>
-</template>
diff --git a/src/views/returnissue/modules/detail-list.vue b/src/views/returnissue/modules/detail-list.vue
deleted file mode 100644
index 23d04ce..0000000
--- a/src/views/returnissue/modules/detail-list.vue
+++ /dev/null
@@ -1,103 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmReturnIssueDetailApi } from '#/api/mes/wm/returnissue/detail';
-
-import { computed, watch } from 'vue';
-
-import { message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import { deleteReturnIssueDetail } from '#/api/mes/wm/returnissue/detail';
-import { $t } from '#/locales';
-
-import { useDetailGridColumns } from '../data';
-
-const props = defineProps<{
- details: MesWmReturnIssueDetailApi.ReturnIssueDetail[];
- formType: FormType;
-}>();
-
-const emit = defineEmits<{
- edit: [detailId: number];
- refresh: [];
-}>();
-
-const isStock = computed(() => props.formType === 'stock'); // 鏄惁涓哄叆搴撲笂鏋舵ā寮�
-
-/** 缂栬緫涓婃灦鏄庣粏 */
-function handleEdit(row: MesWmReturnIssueDetailApi.ReturnIssueDetail) {
- emit('edit', row.id!);
-}
-
-/** 鍒犻櫎涓婃灦鏄庣粏 */
-async function handleDelete(row: MesWmReturnIssueDetailApi.ReturnIssueDetail) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.warehouseName]),
- duration: 0,
- });
- try {
- await deleteReturnIssueDetail(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.warehouseName]));
- emit('refresh');
- } finally {
- hideLoading();
- }
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- gridOptions: {
- border: true,
- columns: useDetailGridColumns(isStock.value),
- data: props.details,
- pagerConfig: {
- enabled: false,
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- size: 'small',
- toolbarConfig: {
- enabled: false,
- },
- } as VxeTableGridOptions<MesWmReturnIssueDetailApi.ReturnIssueDetail>,
-});
-
-watch(
- () => props.details,
- (details) => gridApi.setGridOptions({ data: details }),
-);
-</script>
-
-<template>
- <div class="px-4 py-2">
- <Grid>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [
- row.warehouseName,
- ]),
- confirm: handleDelete.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </div>
-</template>
diff --git a/src/views/returnissue/modules/form.vue b/src/views/returnissue/modules/form.vue
deleted file mode 100644
index ff47948..0000000
--- a/src/views/returnissue/modules/form.vue
+++ /dev/null
@@ -1,222 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { MesWmReturnIssueApi } from '#/api/mes/wm/returnissue';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-import { MesWmReturnIssueStatusEnum } from '@vben/constants';
-
-import { Button, Divider, message, Popconfirm } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createReturnIssue,
- finishReturnIssue,
- getReturnIssue,
- stockReturnIssue,
- submitReturnIssue,
- updateReturnIssue,
-} from '#/api/mes/wm/returnissue';
-import { $t } from '#/locales';
-
-import { useFormSchema } from '../data';
-import LineList from './line-list.vue';
-
-const emit = defineEmits(['success']);
-const formType = ref<FormType>('create');
-const formData = ref<MesWmReturnIssueApi.ReturnIssue>();
-const originalSnapshot = ref(''); // 琛ㄥ崟鍘熷鏁版嵁蹇収锛岀敤浜庢彁浜ゆ椂璺宠繃鏈彉鏇寸殑淇濆瓨璇锋眰
-const isEditable = computed(() =>
- // 鏄惁涓虹紪杈戞ā寮忥紙鍙繚瀛橈級
- ['create', 'update'].includes(formType.value),
-);
-const isStock = computed(() => formType.value === 'stock'); // 鏄惁涓哄叆搴撲笂鏋舵ā寮�
-const isFinish = computed(() => formType.value === 'finish'); // 鏄惁涓烘墽琛岄��鏂欐ā寮�
-const canSubmit = computed(
- () =>
- // 鏄惁鍙彁浜�
- formType.value === 'update' &&
- formData.value?.status === MesWmReturnIssueStatusEnum.PREPARE,
-);
-const getTitle = computed(() => {
- if (formType.value === 'detail') {
- return $t('ui.actionTitle.view', ['鐢熶骇閫�鏂欏崟']);
- }
- if (formType.value === 'stock') {
- return '鍏ュ簱涓婃灦';
- }
- if (formType.value === 'finish') {
- return '鎵ц閫�鏂�';
- }
- return formType.value === 'update'
- ? $t('ui.actionTitle.edit', ['鐢熶骇閫�鏂欏崟'])
- : $t('ui.actionTitle.create', ['鐢熶骇閫�鏂欏崟']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 110,
- },
- layout: 'horizontal',
- schema: [],
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-/** 鎻愪氦閫�鏂欏崟锛氳〃鍗曟湁淇敼鏃跺厛淇濆瓨锛屽啀璋冪敤鎻愪氦鎺ュ彛 */
-async function handleSubmit() {
- const { valid } = await formApi.validate();
- if (!valid || !formData.value?.id) {
- return;
- }
- modalApi.lock();
- try {
- const current = JSON.stringify(await formApi.getValues());
- if (current !== originalSnapshot.value) {
- const data =
- (await formApi.getValues()) as MesWmReturnIssueApi.ReturnIssue;
- await updateReturnIssue({ ...formData.value, ...data });
- originalSnapshot.value = current;
- }
- await submitReturnIssue(formData.value.id);
- message.success('鎻愪氦鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-/** 鍏ュ簱涓婃灦 */
-async function handleStock() {
- if (!formData.value?.id) {
- return;
- }
- modalApi.lock();
- try {
- await stockReturnIssue(formData.value.id);
- message.success('鍏ュ簱涓婃灦鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-/** 鎵ц閫�鏂� */
-async function handleFinish() {
- if (!formData.value?.id) {
- return;
- }
- modalApi.lock();
- try {
- await finishReturnIssue(formData.value.id);
- message.success('瀹屾垚鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- if (!isEditable.value) {
- await modalApi.close();
- return;
- }
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data = (await formApi.getValues()) as MesWmReturnIssueApi.ReturnIssue;
- try {
- if (formData.value?.id) {
- await updateReturnIssue({ ...formData.value, ...data });
- formData.value = { ...formData.value, ...data };
- } else {
- const id = await createReturnIssue(data);
- formData.value = {
- ...data,
- id,
- status: MesWmReturnIssueStatusEnum.PREPARE,
- };
- await formApi.setFieldValue('id', id);
- await formApi.setFieldValue('status', formData.value.status);
- formType.value = 'update';
- }
- originalSnapshot.value = JSON.stringify(await formApi.getValues());
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- originalSnapshot.value = '';
- return;
- }
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{ formType: FormType; id?: number }>();
- formType.value = data.formType;
- formApi.setState({ schema: useFormSchema(formType.value, formApi) });
- formApi.setDisabled(!isEditable.value);
- modalApi.setState({ showConfirmButton: isEditable.value });
- if (data?.id) {
- modalApi.lock();
- try {
- formData.value = await getReturnIssue(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- }
- originalSnapshot.value = JSON.stringify(await formApi.getValues());
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- <!-- 闈炴柊寤烘ā寮忓睍绀虹墿鏂欎俊鎭� -->
- <template v-if="formData?.id">
- <Divider>鐗╂枡淇℃伅</Divider>
- <div class="mx-4">
- <LineList :form-type="formType" :issue-id="formData.id" />
- </div>
- </template>
- <template #prepend-footer>
- <div class="flex flex-auto items-center gap-2">
- <Popconfirm
- v-if="canSubmit"
- title="纭鎻愪氦璇ラ��鏂欏崟锛熴�愭彁浜ゅ悗灏嗕笉鑳戒慨鏀广��"
- @confirm="handleSubmit"
- >
- <Button type="primary">鎻愪氦</Button>
- </Popconfirm>
- <Button v-if="isStock" type="primary" @click="handleStock">
- 鍏ュ簱涓婃灦
- </Button>
- <Popconfirm
- v-if="isFinish"
- title="纭瀹屾垚璇ラ��鏂欏崟骞舵墽琛屽叆搴撳悧锛�"
- @confirm="handleFinish"
- >
- <Button type="primary">鎵ц閫�鏂�</Button>
- </Popconfirm>
- </div>
- </template>
- </Modal>
-</template>
diff --git a/src/views/returnissue/modules/line-form.vue b/src/views/returnissue/modules/line-form.vue
deleted file mode 100644
index 7cdc601..0000000
--- a/src/views/returnissue/modules/line-form.vue
+++ /dev/null
@@ -1,95 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmReturnIssueLineApi } from '#/api/mes/wm/returnissue/line';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createReturnIssueLine,
- getReturnIssueLine,
- updateReturnIssueLine,
-} from '#/api/mes/wm/returnissue/line';
-import { $t } from '#/locales';
-
-import { useLineFormSchema } from '../data';
-
-const emit = defineEmits(['success']);
-const formData = ref<MesWmReturnIssueLineApi.ReturnIssueLine>();
-const issueId = ref<number>(); // 鎵�灞為��鏂欏崟缂栧彿
-
-const getTitle = computed(() => {
- return formData.value?.id
- ? $t('ui.actionTitle.edit', ['鐢熶骇閫�鏂欏崟琛�'])
- : $t('ui.actionTitle.create', ['鐢熶骇閫�鏂欏崟琛�']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 90,
- },
- layout: 'horizontal',
- schema: [],
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data =
- (await formApi.getValues()) as MesWmReturnIssueLineApi.ReturnIssueLine;
- data.issueId = issueId.value;
- try {
- await (formData.value?.id
- ? updateReturnIssueLine({ ...data, id: formData.value.id })
- : createReturnIssueLine(data));
- // 鍏抽棴骞舵彁绀�
- await modalApi.close();
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- return;
- }
- formApi.setState({ schema: useLineFormSchema(formApi) });
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{ id?: number; issueId: number }>();
- issueId.value = data.issueId;
- if (!data.id) {
- return;
- }
- modalApi.lock();
- try {
- formData.value = await getReturnIssueLine(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- </Modal>
-</template>
diff --git a/src/views/returnissue/modules/line-list.vue b/src/views/returnissue/modules/line-list.vue
deleted file mode 100644
index 98c6682..0000000
--- a/src/views/returnissue/modules/line-list.vue
+++ /dev/null
@@ -1,250 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmReturnIssueDetailApi } from '#/api/mes/wm/returnissue/detail';
-import type { MesWmReturnIssueLineApi } from '#/api/mes/wm/returnissue/line';
-
-import { computed, reactive, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-import { BarcodeBizTypeEnum } from '@vben/constants';
-
-import { message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import { getReturnIssueDetailListByLineId } from '#/api/mes/wm/returnissue/detail';
-import {
- deleteReturnIssueLine,
- getReturnIssueLinePage,
-} from '#/api/mes/wm/returnissue/line';
-import { $t } from '#/locales';
-import { BarcodeDetail, PrinterLabel } from '#/views/wls/barcode/components';
-
-import { useLineGridColumns } from '../data';
-import DetailForm from './detail-form.vue';
-import DetailList from './detail-list.vue';
-import LineForm from './line-form.vue';
-
-const props = defineProps<{
- formType: FormType;
- issueId: number;
-}>();
-
-const isEditable = computed(() =>
- // 鏄惁鍙紪杈戞槑缁嗚
- ['create', 'update'].includes(props.formType),
-);
-const isStock = computed(() => props.formType === 'stock'); // 鏄惁涓哄叆搴撲笂鏋舵ā寮�
-const detailMap = reactive<
- Record<number, MesWmReturnIssueDetailApi.ReturnIssueDetail[]>
->({}); // 宸插睍寮�琛岀殑涓婃灦鏄庣粏缂撳瓨
-const barcodeDetailRef = ref(); // 鏉$爜璇︽儏寮圭獥瀹炰緥
-
-const [LineFormModal, lineFormModalApi] = useVbenModal({
- connectedComponent: LineForm,
- destroyOnClose: true,
-});
-
-const [DetailFormModal, detailFormModalApi] = useVbenModal({
- connectedComponent: DetailForm,
- destroyOnClose: true,
-});
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- for (const id of Object.keys(detailMap)) {
- delete detailMap[Number(id)];
- }
- gridApi.query();
-}
-
-/** 娣诲姞鐗╂枡 */
-function handleCreate() {
- lineFormModalApi.setData({ issueId: props.issueId }).open();
-}
-
-/** 缂栬緫鐗╂枡 */
-function handleEdit(row: MesWmReturnIssueLineApi.ReturnIssueLine) {
- lineFormModalApi.setData({ id: row.id, issueId: props.issueId }).open();
-}
-
-/** 鍒犻櫎鐗╂枡 */
-async function handleDelete(row: MesWmReturnIssueLineApi.ReturnIssueLine) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.itemName]),
- duration: 0,
- });
- try {
- await deleteReturnIssueLine(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.itemName]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-/** 涓婃灦锛氱洿鎺ユ墦寮�鏄庣粏鍒涘缓琛ㄥ崟 */
-function handlePicking(row: MesWmReturnIssueLineApi.ReturnIssueLine) {
- openDetailForm(row.id!, row.itemId);
-}
-
-/** 鏌ョ湅鐗╂枡鏉$爜 */
-function handleBarcode(row: MesWmReturnIssueLineApi.ReturnIssueLine) {
- barcodeDetailRef.value?.openByBusiness(
- row.itemId,
- BarcodeBizTypeEnum.ITEM,
- row.itemCode,
- row.itemName,
- );
-}
-
-/** 鎵撳紑涓婃灦鏄庣粏琛ㄥ崟 */
-function openDetailForm(lineId: number, itemId?: number, detailId?: number) {
- detailFormModalApi
- .setData({ detailId, issueId: props.issueId, itemId, lineId })
- .open();
-}
-
-/** 鑾峰彇宸插睍寮�琛岀殑涓婃灦鏄庣粏 */
-function getExpandedDetails(row: MesWmReturnIssueLineApi.ReturnIssueLine) {
- return detailMap[row.id!] || [];
-}
-
-/** 鍔犺浇鎸囧畾琛岀殑涓婃灦鏄庣粏 */
-async function loadLineDetails(lineId: number) {
- detailMap[lineId] = await getReturnIssueDetailListByLineId(lineId);
-}
-
-/** 灞曞紑琛屾椂鎳掑姞杞戒笂鏋舵槑缁� */
-async function handleExpandChange(
- row: MesWmReturnIssueLineApi.ReturnIssueLine,
- expanded: boolean,
-) {
- if (!expanded) {
- return;
- }
- await loadLineDetails(row.id!);
-}
-
-/** 鏄庣粏琛ㄥ崟鎻愪氦鎴愬姛鍚庯紝鍒锋柊瀵瑰簲琛屽凡灞曞紑鐨勬槑缁� */
-async function handleDetailSuccess(lineId: number) {
- await loadLineDetails(lineId);
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- gridOptions: {
- columns: useLineGridColumns(isEditable.value, isStock.value),
- expandConfig: {
- padding: true,
- },
- height: 400,
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }) => {
- if (!props.issueId) {
- return { list: [], total: 0 };
- }
- return await getReturnIssueLinePage({
- issueId: props.issueId,
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- },
- } as VxeTableGridOptions<MesWmReturnIssueLineApi.ReturnIssueLine>,
- gridEvents: {
- toggleRowExpand: ({
- expanded,
- row,
- }: {
- expanded: boolean;
- row: MesWmReturnIssueLineApi.ReturnIssueLine;
- }) => {
- handleExpandChange(row, expanded);
- },
- },
-});
-</script>
-
-<template>
- <div>
- <LineFormModal @success="handleRefresh" />
- <DetailFormModal @success="handleDetailSuccess" />
- <Grid table-title="鐗╂枡淇℃伅">
- <template v-if="isEditable" #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: '娣诲姞鐗╂枡',
- type: 'primary',
- icon: ACTION_ICON.ADD,
- onClick: handleCreate,
- },
- ]"
- />
- </template>
- <template #detail="{ row }">
- <DetailList
- :details="getExpandedDetails(row)"
- :form-type="formType"
- @edit="(detailId) => openDetailForm(row.id!, row.itemId, detailId)"
- @refresh="loadLineDetails(row.id!)"
- />
- </template>
- <template #actions="{ row }">
- <div class="flex items-center justify-center">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- ifShow: isEditable,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- ifShow: isEditable,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.itemName]),
- confirm: handleDelete.bind(null, row),
- },
- },
- {
- label: '涓婃灦',
- type: 'link',
- ifShow: isStock,
- onClick: handlePicking.bind(null, row),
- },
- {
- label: '鏉$爜',
- type: 'link',
- onClick: handleBarcode.bind(null, row),
- },
- ]"
- />
- <PrinterLabel
- v-if="isStock"
- :biz-code="row.batchCode"
- :biz-id="row.batchId"
- biz-type="BATCH"
- />
- </div>
- </template>
- </Grid>
- <BarcodeDetail ref="barcodeDetailRef" />
- </div>
-</template>
diff --git a/src/views/returnsales/data.ts b/src/views/returnsales/data.ts
deleted file mode 100644
index e926283..0000000
--- a/src/views/returnsales/data.ts
+++ /dev/null
@@ -1,515 +0,0 @@
-import type { VbenFormApi, VbenFormSchema } from '#/adapter/form';
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmReturnSalesApi } from '#/api/mes/wm/returnsales';
-import type { MesWmReturnSalesDetailApi } from '#/api/mes/wm/returnsales/detail';
-import type { MesWmReturnSalesLineApi } from '#/api/mes/wm/returnsales/line';
-
-import { h, markRaw } from 'vue';
-
-import { DICT_TYPE, MesAutoCodeRuleCode } from '@vben/constants';
-import { getDictOptions } from '@vben/hooks';
-
-import { Button } from 'ant-design-vue';
-
-import { z } from '#/adapter/form';
-import { generateAutoCode } from '#/api/mes/md/autocode/record';
-import { MdClientSelect } from '#/views/mes/md/client/components';
-import { MdItemSelect } from '#/views/mes/md/item/components';
-import { WmBatchSelect } from '#/views/wls/batch/components';
-import {
- WmWarehouseAreaSelect,
- WmWarehouseLocationSelect,
- WmWarehouseSelect,
-} from '#/views/wls/warehouse/components';
-
-/** 琛ㄥ崟绫诲瀷 */
-export type FormType = 'create' | 'detail' | 'finish' | 'stock' | 'update';
-
-/** 琛ㄥ崟澶撮儴鏄惁鍙锛堜笂鏋躲�佽鎯呫�佹墽琛岄��璐ф�侊級 */
-function isHeaderReadonly(formType: FormType): boolean {
- return formType === 'detail' || formType === 'finish' || formType === 'stock';
-}
-
-/** 鏂板/淇敼鐨勮〃鍗� */
-export function useFormSchema(
- formType: FormType,
- formApi?: VbenFormApi,
-): VbenFormSchema[] {
- return [
- {
- fieldName: 'id',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'status',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'code',
- label: '閫�璐у崟缂栧彿',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ラ��璐у崟缂栧彿',
- },
- rules: 'required',
- suffix: isHeaderReadonly(formType)
- ? undefined
- : () =>
- h(
- Button,
- {
- type: 'default',
- onClick: async () => {
- const code = await generateAutoCode(
- MesAutoCodeRuleCode.WM_RETURN_SALES_CODE,
- );
- await formApi?.setFieldValue('code', code);
- },
- },
- { default: () => '鐢熸垚' },
- ),
- },
- {
- fieldName: 'name',
- label: '閫�璐у崟鍚嶇О',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ラ��璐у崟鍚嶇О',
- },
- rules: 'required',
- },
- {
- fieldName: 'salesOrderCode',
- label: '閿�鍞鍗曞彿',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ラ攢鍞鍗曞彿',
- },
- },
- {
- fieldName: 'clientId',
- label: '瀹㈡埛',
- component: markRaw(MdClientSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨瀹㈡埛',
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'returnDate',
- label: '閫�璐ф棩鏈�',
- component: 'DatePicker',
- componentProps: {
- class: '!w-full',
- format: 'YYYY-MM-DD',
- placeholder: '璇烽�夋嫨閫�璐ф棩鏈�',
- valueFormat: 'x',
- },
- rules: 'required',
- },
- {
- fieldName: 'returnReason',
- label: '閫�璐у師鍥�',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- placeholder: '璇疯緭鍏ラ��璐у師鍥�',
- rows: 2,
- },
- rules: 'required',
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勬悳绱㈣〃鍗� */
-export function useGridFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'code',
- label: '閫�璐у崟缂栧彿',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ラ��璐у崟缂栧彿',
- },
- },
- {
- fieldName: 'name',
- label: '閫�璐у崟鍚嶇О',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ラ��璐у崟鍚嶇О',
- },
- },
- {
- fieldName: 'salesOrderCode',
- label: '閿�鍞鍗曞彿',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ラ攢鍞鍗曞彿',
- },
- },
- {
- fieldName: 'clientId',
- label: '瀹㈡埛',
- component: markRaw(MdClientSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨瀹㈡埛',
- },
- },
- {
- fieldName: 'status',
- label: '鍗曟嵁鐘舵��',
- component: 'Select',
- componentProps: {
- allowClear: true,
- options: getDictOptions(DICT_TYPE.MES_WM_RETURN_SALES_STATUS, 'number'),
- placeholder: '璇烽�夋嫨鍗曟嵁鐘舵��',
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勫瓧娈� */
-export function useGridColumns(): VxeTableGridOptions<MesWmReturnSalesApi.ReturnSales>['columns'] {
- return [
- {
- field: 'code',
- title: '閫�璐у崟缂栧彿',
- minWidth: 160,
- slots: { default: 'code' },
- },
- {
- field: 'name',
- title: '閫�璐у崟鍚嶇О',
- minWidth: 150,
- },
- {
- field: 'salesOrderCode',
- title: '閿�鍞鍗曞彿',
- minWidth: 140,
- },
- {
- field: 'clientCode',
- title: '瀹㈡埛缂栫爜',
- minWidth: 120,
- },
- {
- field: 'clientName',
- title: '瀹㈡埛鍚嶇О',
- minWidth: 150,
- },
- {
- field: 'returnReason',
- title: '閫�璐у師鍥�',
- minWidth: 150,
- },
- {
- field: 'returnDate',
- title: '閫�璐ф棩鏈�',
- width: 180,
- formatter: 'formatDate',
- },
- {
- field: 'status',
- title: '鍗曟嵁鐘舵��',
- minWidth: 110,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_RETURN_SALES_STATUS },
- },
- },
- {
- title: '鎿嶄綔',
- width: 240,
- fixed: 'right',
- slots: { default: 'actions' },
- },
- ];
-}
-
-/** 閫�璐у崟琛屽瓙琛ㄧ殑瀛楁 */
-export function useLineGridColumns(
- editable: boolean,
- stockable: boolean,
-): VxeTableGridOptions<MesWmReturnSalesLineApi.ReturnSalesLine>['columns'] {
- return [
- {
- type: 'expand',
- width: 48,
- slots: { content: 'detail' },
- },
- {
- field: 'itemCode',
- title: '鐗╂枡缂栫爜',
- minWidth: 120,
- },
- {
- field: 'itemName',
- title: '鐗╂枡鍚嶇О',
- minWidth: 140,
- },
- {
- field: 'specification',
- title: '瑙勬牸鍨嬪彿',
- minWidth: 120,
- },
- {
- field: 'unitMeasureName',
- title: '鍗曚綅',
- width: 80,
- },
- {
- field: 'quantity',
- title: '閫�璐ф暟閲�',
- width: 100,
- },
- {
- field: 'batchCode',
- title: '鎵规鍙�',
- minWidth: 120,
- },
- {
- field: 'rqcCheckFlag',
- title: '鏄惁闇�瑕佽川妫�',
- width: 120,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.INFRA_BOOLEAN_STRING },
- },
- },
- {
- field: 'qualityStatus',
- title: '璐ㄩ噺鐘舵��',
- width: 100,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_QUALITY_STATUS },
- },
- },
- ...(editable || stockable
- ? [
- {
- title: '鎿嶄綔',
- width: 160,
- fixed: 'right',
- slots: { default: 'actions' },
- } as const,
- ]
- : []),
- ];
-}
-
-/** 閫�璐у崟琛屾柊澧�/淇敼鐨勮〃鍗� */
-export function useLineFormSchema(
- clientId?: number,
- salesOrderCode?: string,
-): VbenFormSchema[] {
- return [
- {
- fieldName: 'itemId',
- label: '鐗╂枡',
- component: markRaw(MdItemSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨鐗╂枡',
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'quantity',
- label: '閫�璐ф暟閲�',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0,
- placeholder: '璇疯緭鍏ラ��璐ф暟閲�',
- precision: 2,
- },
- rules: 'required',
- },
- {
- fieldName: 'batchId',
- label: '鎵规',
- component: markRaw(WmBatchSelect),
- componentProps: {
- clientId,
- placeholder: '璇烽�夋嫨鎵规',
- salesOrderCode,
- },
- dependencies: {
- triggerFields: ['itemId'],
- componentProps: (values) => ({
- clientId,
- itemId: values.itemId,
- placeholder: '璇烽�夋嫨鎵规',
- salesOrderCode,
- }),
- },
- },
- {
- fieldName: 'rqcCheckFlag',
- label: '闇�瑕佽川妫�',
- component: 'Switch',
- rules: z.boolean().default(false),
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
-
-/** 涓婃灦鏄庣粏瀛愯〃鐨勫瓧娈� */
-export function useDetailGridColumns(
- stockable: boolean,
-): VxeTableGridOptions<MesWmReturnSalesDetailApi.ReturnSalesDetail>['columns'] {
- return [
- {
- field: 'batchCode',
- title: '鎵规鍙�',
- minWidth: 120,
- },
- {
- field: 'warehouseName',
- title: '浠撳簱鍚嶇О',
- minWidth: 100,
- },
- {
- field: 'locationName',
- title: '搴撳尯鍚嶇О',
- minWidth: 100,
- },
- {
- field: 'areaName',
- title: '搴撲綅鍚嶇О',
- minWidth: 100,
- },
- {
- field: 'quantity',
- title: '鏁伴噺',
- width: 100,
- },
- ...(stockable
- ? [
- {
- title: '鎿嶄綔',
- width: 120,
- fixed: 'right',
- slots: { default: 'actions' },
- } as const,
- ]
- : []),
- ];
-}
-
-/** 涓婃灦鏄庣粏鏂板/淇敼鐨勮〃鍗� */
-export function useDetailFormSchema(formApi?: VbenFormApi): VbenFormSchema[] {
- return [
- {
- fieldName: 'itemId',
- label: '鐗╂枡',
- component: markRaw(MdItemSelect),
- componentProps: {
- disabled: true,
- },
- },
- {
- fieldName: 'warehouseId',
- label: '鍏ュ簱浠撳簱',
- component: markRaw(WmWarehouseSelect),
- componentProps: {
- // 鍒囨崲浠撳簱鍚庢竻绌哄簱鍖哄拰搴撲綅
- onChange: async () => {
- await formApi?.setValues({
- areaId: undefined,
- locationId: undefined,
- });
- },
- placeholder: '璇烽�夋嫨浠撳簱',
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'locationId',
- label: '搴撳尯',
- component: markRaw(WmWarehouseLocationSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨搴撳尯',
- },
- rules: 'selectRequired',
- dependencies: {
- triggerFields: ['warehouseId'],
- componentProps: (values) => ({
- // 鍒囨崲搴撳尯鍚庢竻绌哄簱浣�
- onChange: async () => {
- await formApi?.setFieldValue('areaId', undefined);
- },
- placeholder: '璇烽�夋嫨搴撳尯',
- warehouseId: values.warehouseId,
- }),
- },
- },
- {
- fieldName: 'areaId',
- label: '搴撲綅',
- component: markRaw(WmWarehouseAreaSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨搴撲綅',
- },
- rules: 'selectRequired',
- dependencies: {
- triggerFields: ['locationId'],
- componentProps: (values) => ({
- locationId: values.locationId,
- placeholder: '璇烽�夋嫨搴撲綅',
- }),
- },
- },
- {
- fieldName: 'batchCode',
- label: '鎵规鍙�',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ユ壒娆″彿',
- },
- },
- {
- fieldName: 'quantity',
- label: '鏁伴噺',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0,
- placeholder: '璇疯緭鍏ユ暟閲�',
- precision: 2,
- },
- rules: 'required',
- },
- ];
-}
diff --git a/src/views/returnsales/index.vue b/src/views/returnsales/index.vue
deleted file mode 100644
index 7339a67..0000000
--- a/src/views/returnsales/index.vue
+++ /dev/null
@@ -1,213 +0,0 @@
-<script lang="ts" setup>
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmReturnSalesApi } from '#/api/mes/wm/returnsales';
-
-import { Page, useVbenModal } from '@vben/common-ui';
-import { MesWmReturnSalesStatusEnum } from '@vben/constants';
-import { downloadFileFromBlobPart } from '@vben/utils';
-
-import { Button, message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import {
- cancelReturnSales,
- deleteReturnSales,
- exportReturnSales,
- getReturnSalesPage,
-} from '#/api/mes/wm/returnsales';
-import { $t } from '#/locales';
-
-import { useGridColumns, useGridFormSchema } from './data';
-import Form from './modules/form.vue';
-
-const [FormModal, formModalApi] = useVbenModal({
- connectedComponent: Form,
- destroyOnClose: true,
-});
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- gridApi.query();
-}
-
-/** 鍒涘缓閿�鍞��璐у崟 */
-function handleCreate() {
- formModalApi.setData({ formType: 'create' }).open();
-}
-
-/** 鏌ョ湅閿�鍞��璐у崟 */
-function handleDetail(row: MesWmReturnSalesApi.ReturnSales) {
- formModalApi.setData({ formType: 'detail', id: row.id }).open();
-}
-
-/** 缂栬緫閿�鍞��璐у崟 */
-function handleEdit(row: MesWmReturnSalesApi.ReturnSales) {
- formModalApi.setData({ formType: 'update', id: row.id }).open();
-}
-
-/** 鎵ц涓婃灦 */
-function handleStock(row: MesWmReturnSalesApi.ReturnSales) {
- formModalApi.setData({ formType: 'stock', id: row.id }).open();
-}
-
-/** 鎵ц閫�璐� */
-function handleFinish(row: MesWmReturnSalesApi.ReturnSales) {
- formModalApi.setData({ formType: 'finish', id: row.id }).open();
-}
-
-/** 鎻愮ず鍓嶅線璐ㄦ妯″潡 */
-function handleQc() {
- message.info('璇峰墠寰�銆愯川閲忕鐞� - 閫�璐ф楠岋紙RQC锛夈�戜腑杩涜閫�璐ф楠屾搷浣�');
-}
-
-/** 鍒犻櫎閿�鍞��璐у崟 */
-async function handleDelete(row: MesWmReturnSalesApi.ReturnSales) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.code]),
- duration: 0,
- });
- try {
- await deleteReturnSales(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.code]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-/** 鍙栨秷閿�鍞��璐у崟 */
-async function handleCancel(row: MesWmReturnSalesApi.ReturnSales) {
- await cancelReturnSales(row.id!);
- message.success('鍙栨秷鎴愬姛');
- handleRefresh();
-}
-
-/** 瀵煎嚭琛ㄦ牸 */
-async function handleExport() {
- const data = await exportReturnSales(await gridApi.formApi.getValues());
- downloadFileFromBlobPart({ fileName: '閿�鍞��璐у崟.xls', source: data });
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- formOptions: {
- schema: useGridFormSchema(),
- },
- gridOptions: {
- columns: useGridColumns(),
- height: 'auto',
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }, formValues) => {
- return await getReturnSalesPage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- ...formValues,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- search: true,
- },
- } as VxeTableGridOptions<MesWmReturnSalesApi.ReturnSales>,
-});
-</script>
-
-<template>
- <Page auto-content-height><FormModal @success="handleRefresh" />
-
- <Grid table-title="閿�鍞��璐у崟鍒楄〃">
- <template #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: $t('ui.actionTitle.create', ['閿�鍞��璐у崟']),
- type: 'primary',
- icon: ACTION_ICON.ADD,
- auth: ['mes:wm-return-sales:create'],
- onClick: handleCreate,
- },
- {
- label: $t('ui.actionTitle.export'),
- type: 'primary',
- icon: ACTION_ICON.DOWNLOAD,
- auth: ['mes:wm-return-sales:export'],
- onClick: handleExport,
- },
- ]"
- />
- </template>
- <template #code="{ row }">
- <Button type="link" @click="handleDetail(row)">
- {{ row.code }}
- </Button>
- </template>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- auth: ['mes:wm-return-sales:update'],
- ifShow: row.status === MesWmReturnSalesStatusEnum.PREPARE,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- auth: ['mes:wm-return-sales:delete'],
- ifShow: row.status === MesWmReturnSalesStatusEnum.PREPARE,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.code]),
- confirm: handleDelete.bind(null, row),
- },
- },
- {
- label: '鎵ц璐ㄦ',
- type: 'link',
- ifShow: row.status === MesWmReturnSalesStatusEnum.CONFIRMED,
- onClick: handleQc,
- },
- {
- label: '鎵ц閫�璐�',
- type: 'link',
- auth: ['mes:wm-return-sales:finish'],
- ifShow: row.status === MesWmReturnSalesStatusEnum.APPROVING,
- onClick: handleFinish.bind(null, row),
- },
- {
- label: '鎵ц涓婃灦',
- type: 'link',
- auth: ['mes:wm-return-sales:stock'],
- ifShow: row.status === MesWmReturnSalesStatusEnum.APPROVED,
- onClick: handleStock.bind(null, row),
- },
- {
- label: '鍙栨秷',
- type: 'link',
- danger: true,
- auth: ['mes:wm-return-sales:cancel'],
- ifShow:
- row.status === MesWmReturnSalesStatusEnum.CONFIRMED ||
- row.status === MesWmReturnSalesStatusEnum.APPROVING ||
- row.status === MesWmReturnSalesStatusEnum.APPROVED,
- popConfirm: {
- title: '纭鍙栨秷璇ラ攢鍞��璐у崟锛熷彇娑堝悗涓嶅彲鎭㈠銆�',
- confirm: handleCancel.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </Page>
-</template>
diff --git a/src/views/returnsales/modules/detail-form.vue b/src/views/returnsales/modules/detail-form.vue
deleted file mode 100644
index 7fe34f7..0000000
--- a/src/views/returnsales/modules/detail-form.vue
+++ /dev/null
@@ -1,104 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmReturnSalesDetailApi } from '#/api/mes/wm/returnsales/detail';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createReturnSalesDetail,
- getReturnSalesDetail,
- updateReturnSalesDetail,
-} from '#/api/mes/wm/returnsales/detail';
-import { $t } from '#/locales';
-
-import { useDetailFormSchema } from '../data';
-
-const emit = defineEmits<{ success: [lineId: number] }>();
-const formData = ref<MesWmReturnSalesDetailApi.ReturnSalesDetail>();
-const returnId = ref<number>(); // 鎵�灞為��璐у崟缂栧彿
-const lineId = ref<number>(); // 鎵�灞為��璐у崟琛岀紪鍙�
-
-const getTitle = computed(() => {
- return formData.value?.id
- ? $t('ui.actionTitle.edit', ['涓婃灦鏄庣粏'])
- : $t('ui.actionTitle.create', ['涓婃灦鏄庣粏']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 90,
- },
- layout: 'horizontal',
- schema: useDetailFormSchema(),
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data =
- (await formApi.getValues()) as MesWmReturnSalesDetailApi.ReturnSalesDetail;
- data.returnId = returnId.value;
- data.lineId = lineId.value;
- try {
- await (formData.value?.id
- ? updateReturnSalesDetail({ ...data, id: formData.value.id })
- : createReturnSalesDetail(data));
- // 鍏抽棴骞舵彁绀�
- await modalApi.close();
- emit('success', lineId.value!);
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- return;
- }
- formApi.setState({ schema: useDetailFormSchema(formApi) });
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{
- detailId?: number;
- itemId?: number;
- lineId: number;
- returnId: number;
- }>();
- returnId.value = data.returnId;
- lineId.value = data.lineId;
- if (data.detailId) {
- modalApi.lock();
- try {
- formData.value = await getReturnSalesDetail(data.detailId);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- } else if (data.itemId) {
- await formApi.setFieldValue('itemId', data.itemId);
- }
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- </Modal>
-</template>
diff --git a/src/views/returnsales/modules/detail-list.vue b/src/views/returnsales/modules/detail-list.vue
deleted file mode 100644
index 7c0ca9a..0000000
--- a/src/views/returnsales/modules/detail-list.vue
+++ /dev/null
@@ -1,103 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmReturnSalesDetailApi } from '#/api/mes/wm/returnsales/detail';
-
-import { computed, watch } from 'vue';
-
-import { message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import { deleteReturnSalesDetail } from '#/api/mes/wm/returnsales/detail';
-import { $t } from '#/locales';
-
-import { useDetailGridColumns } from '../data';
-
-const props = defineProps<{
- details: MesWmReturnSalesDetailApi.ReturnSalesDetail[];
- formType: FormType;
-}>();
-
-const emit = defineEmits<{
- edit: [detailId: number];
- refresh: [];
-}>();
-
-const isStock = computed(() => props.formType === 'stock'); // 鏄惁涓轰笂鏋舵ā寮�
-
-/** 缂栬緫涓婃灦鏄庣粏 */
-function handleEdit(row: MesWmReturnSalesDetailApi.ReturnSalesDetail) {
- emit('edit', row.id!);
-}
-
-/** 鍒犻櫎涓婃灦鏄庣粏 */
-async function handleDelete(row: MesWmReturnSalesDetailApi.ReturnSalesDetail) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.warehouseName]),
- duration: 0,
- });
- try {
- await deleteReturnSalesDetail(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.warehouseName]));
- emit('refresh');
- } finally {
- hideLoading();
- }
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- gridOptions: {
- border: true,
- columns: useDetailGridColumns(isStock.value),
- data: props.details,
- pagerConfig: {
- enabled: false,
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- size: 'small',
- toolbarConfig: {
- enabled: false,
- },
- } as VxeTableGridOptions<MesWmReturnSalesDetailApi.ReturnSalesDetail>,
-});
-
-watch(
- () => props.details,
- (details) => gridApi.setGridOptions({ data: details }),
-);
-</script>
-
-<template>
- <div class="px-4 py-2">
- <Grid>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [
- row.warehouseName,
- ]),
- confirm: handleDelete.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </div>
-</template>
diff --git a/src/views/returnsales/modules/form.vue b/src/views/returnsales/modules/form.vue
deleted file mode 100644
index 3cae020..0000000
--- a/src/views/returnsales/modules/form.vue
+++ /dev/null
@@ -1,231 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { MesWmReturnSalesApi } from '#/api/mes/wm/returnsales';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-import { MesWmReturnSalesStatusEnum } from '@vben/constants';
-
-import { Button, Divider, message, Popconfirm } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createReturnSales,
- finishReturnSales,
- getReturnSales,
- stockReturnSales,
- submitReturnSales,
- updateReturnSales,
-} from '#/api/mes/wm/returnsales';
-import { $t } from '#/locales';
-
-import { useFormSchema } from '../data';
-import LineList from './line-list.vue';
-
-const emit = defineEmits(['success']);
-const formType = ref<FormType>('create');
-const formData = ref<MesWmReturnSalesApi.ReturnSales>();
-const originalSnapshot = ref(''); // 琛ㄥ崟鍘熷鏁版嵁蹇収锛岀敤浜庢彁浜ゆ椂璺宠繃鏈彉鏇寸殑淇濆瓨璇锋眰
-const isEditable = computed(() =>
- // 鏄惁涓虹紪杈戞ā寮忥紙鍙繚瀛橈級
- ['create', 'update'].includes(formType.value),
-);
-const isStock = computed(() => formType.value === 'stock'); // 鏄惁涓轰笂鏋舵ā寮�
-const isFinish = computed(() => formType.value === 'finish'); // 鏄惁涓烘墽琛岄��璐фā寮�
-const canSubmit = computed(
- () =>
- // 鏄惁鍙彁浜�
- formType.value === 'update' &&
- formData.value?.status === MesWmReturnSalesStatusEnum.PREPARE,
-);
-const getTitle = computed(() => {
- if (formType.value === 'detail') {
- return $t('ui.actionTitle.view', ['閿�鍞��璐у崟']);
- }
- if (formType.value === 'stock') {
- return '鎵ц涓婃灦';
- }
- if (formType.value === 'finish') {
- return '鎵ц閫�璐�';
- }
- return formType.value === 'update'
- ? $t('ui.actionTitle.edit', ['閿�鍞��璐у崟'])
- : $t('ui.actionTitle.create', ['閿�鍞��璐у崟']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 110,
- },
- layout: 'horizontal',
- schema: [],
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-/** 鎻愪氦閫�璐у崟锛氳〃鍗曟湁淇敼鏃跺厛淇濆瓨锛屽啀璋冪敤鎻愪氦鎺ュ彛 */
-async function handleSubmit() {
- const { valid } = await formApi.validate();
- if (!valid || !formData.value?.id) {
- return;
- }
- modalApi.lock();
- try {
- const current = JSON.stringify(await formApi.getValues());
- if (current !== originalSnapshot.value) {
- const data =
- (await formApi.getValues()) as MesWmReturnSalesApi.ReturnSales;
- await updateReturnSales({ ...formData.value, ...data });
- originalSnapshot.value = current;
- }
- await submitReturnSales(formData.value.id);
- message.success('鎻愪氦鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-/** 鎵ц涓婃灦 */
-async function handleStock() {
- if (!formData.value?.id) {
- return;
- }
- modalApi.lock();
- try {
- await stockReturnSales(formData.value.id);
- message.success('涓婃灦鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-/** 鎵ц閫�璐� */
-async function handleFinish() {
- if (!formData.value?.id) {
- return;
- }
- modalApi.lock();
- try {
- await finishReturnSales(formData.value.id);
- message.success('鎵ц閫�璐ф垚鍔�');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- if (!isEditable.value) {
- await modalApi.close();
- return;
- }
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data = (await formApi.getValues()) as MesWmReturnSalesApi.ReturnSales;
- try {
- if (formData.value?.id) {
- await updateReturnSales({ ...formData.value, ...data });
- formData.value = { ...formData.value, ...data };
- } else {
- const id = await createReturnSales(data);
- formData.value = {
- ...data,
- id,
- status: MesWmReturnSalesStatusEnum.PREPARE,
- };
- await formApi.setFieldValue('id', id);
- await formApi.setFieldValue('status', formData.value.status);
- formType.value = 'update';
- }
- originalSnapshot.value = JSON.stringify(await formApi.getValues());
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- originalSnapshot.value = '';
- return;
- }
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{ formType: FormType; id?: number }>();
- formType.value = data.formType;
- formApi.setState({ schema: useFormSchema(formType.value, formApi) });
- formApi.setDisabled(!isEditable.value);
- modalApi.setState({ showConfirmButton: isEditable.value });
- if (data?.id) {
- modalApi.lock();
- try {
- formData.value = await getReturnSales(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- }
- originalSnapshot.value = JSON.stringify(await formApi.getValues());
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- <!-- 闈炴柊寤烘ā寮忓睍绀虹墿鏂欎俊鎭� -->
- <template v-if="formData?.id">
- <Divider>鐗╂枡淇℃伅</Divider>
- <div class="mx-4">
- <LineList
- :client-id="formData.clientId"
- :form-type="formType"
- :return-id="formData.id"
- :sales-order-code="formData.salesOrderCode"
- />
- </div>
- </template>
- <template #prepend-footer>
- <div class="flex flex-auto items-center gap-2">
- <Popconfirm
- v-if="canSubmit"
- title="纭鎻愪氦璇ラ攢鍞��璐у崟锛熴�愭彁浜ゅ悗灏嗕笉鑳戒慨鏀广��"
- @confirm="handleSubmit"
- >
- <Button type="primary">鎻愪氦</Button>
- </Popconfirm>
- <Popconfirm
- v-if="isStock"
- title="纭鎵ц涓婃灦锛�"
- @confirm="handleStock"
- >
- <Button type="primary">鎵ц涓婃灦</Button>
- </Popconfirm>
- <Popconfirm
- v-if="isFinish"
- title="纭鎵ц閫�璐э紵鎵ц鍚庡皢杩涘叆寰呬笂鏋剁姸鎬併��"
- @confirm="handleFinish"
- >
- <Button type="primary">鎵ц閫�璐�</Button>
- </Popconfirm>
- </div>
- </template>
- </Modal>
-</template>
diff --git a/src/views/returnsales/modules/line-form.vue b/src/views/returnsales/modules/line-form.vue
deleted file mode 100644
index 0736b8b..0000000
--- a/src/views/returnsales/modules/line-form.vue
+++ /dev/null
@@ -1,102 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmReturnSalesLineApi } from '#/api/mes/wm/returnsales/line';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createReturnSalesLine,
- getReturnSalesLine,
- updateReturnSalesLine,
-} from '#/api/mes/wm/returnsales/line';
-import { $t } from '#/locales';
-
-import { useLineFormSchema } from '../data';
-
-const emit = defineEmits(['success']);
-const formData = ref<MesWmReturnSalesLineApi.ReturnSalesLine>();
-const returnId = ref<number>(); // 鎵�灞為��璐у崟缂栧彿
-
-const getTitle = computed(() => {
- return formData.value?.id
- ? $t('ui.actionTitle.edit', ['閿�鍞��璐у崟琛�'])
- : $t('ui.actionTitle.create', ['閿�鍞��璐у崟琛�']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 90,
- },
- layout: 'horizontal',
- schema: [],
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data =
- (await formApi.getValues()) as MesWmReturnSalesLineApi.ReturnSalesLine;
- data.returnId = returnId.value;
- try {
- await (formData.value?.id
- ? updateReturnSalesLine({ ...data, id: formData.value.id })
- : createReturnSalesLine(data));
- // 鍏抽棴骞舵彁绀�
- await modalApi.close();
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- return;
- }
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{
- clientId?: number;
- id?: number;
- returnId: number;
- salesOrderCode?: string;
- }>();
- returnId.value = data.returnId;
- formApi.setState({
- schema: useLineFormSchema(data.clientId, data.salesOrderCode),
- });
- if (!data.id) {
- return;
- }
- modalApi.lock();
- try {
- formData.value = await getReturnSalesLine(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- </Modal>
-</template>
diff --git a/src/views/returnsales/modules/line-list.vue b/src/views/returnsales/modules/line-list.vue
deleted file mode 100644
index d1ab690..0000000
--- a/src/views/returnsales/modules/line-list.vue
+++ /dev/null
@@ -1,247 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmReturnSalesDetailApi } from '#/api/mes/wm/returnsales/detail';
-import type { MesWmReturnSalesLineApi } from '#/api/mes/wm/returnsales/line';
-
-import { computed, reactive } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import { getReturnSalesDetailListByLineId } from '#/api/mes/wm/returnsales/detail';
-import {
- deleteReturnSalesLine,
- getReturnSalesLinePage,
-} from '#/api/mes/wm/returnsales/line';
-import { $t } from '#/locales';
-import { PrinterLabel } from '#/views/wls/barcode/components';
-
-import { useLineGridColumns } from '../data';
-import DetailForm from './detail-form.vue';
-import DetailList from './detail-list.vue';
-import LineForm from './line-form.vue';
-
-const props = defineProps<{
- clientId?: number;
- formType: FormType;
- returnId: number;
- salesOrderCode?: string;
-}>();
-
-const isEditable = computed(() =>
- // 鏄惁鍙紪杈戞槑缁嗚
- ['create', 'update'].includes(props.formType),
-);
-const isStock = computed(() => props.formType === 'stock'); // 鏄惁涓轰笂鏋舵ā寮�
-const detailMap = reactive<
- Record<number, MesWmReturnSalesDetailApi.ReturnSalesDetail[]>
->({}); // 宸插睍寮�琛岀殑涓婃灦鏄庣粏缂撳瓨
-
-const [LineFormModal, lineFormModalApi] = useVbenModal({
- connectedComponent: LineForm,
- destroyOnClose: true,
-});
-
-const [DetailFormModal, detailFormModalApi] = useVbenModal({
- connectedComponent: DetailForm,
- destroyOnClose: true,
-});
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- for (const id of Object.keys(detailMap)) {
- delete detailMap[Number(id)];
- }
- gridApi.query();
-}
-
-/** 娣诲姞鐗╂枡 */
-function handleCreate() {
- lineFormModalApi
- .setData({
- clientId: props.clientId,
- returnId: props.returnId,
- salesOrderCode: props.salesOrderCode,
- })
- .open();
-}
-
-/** 缂栬緫鐗╂枡 */
-function handleEdit(row: MesWmReturnSalesLineApi.ReturnSalesLine) {
- lineFormModalApi
- .setData({
- clientId: props.clientId,
- id: row.id,
- returnId: props.returnId,
- salesOrderCode: props.salesOrderCode,
- })
- .open();
-}
-
-/** 鍒犻櫎鐗╂枡 */
-async function handleDelete(row: MesWmReturnSalesLineApi.ReturnSalesLine) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.itemName]),
- duration: 0,
- });
- try {
- await deleteReturnSalesLine(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.itemName]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-/** 涓婃灦锛氱洿鎺ユ墦寮�鏄庣粏鍒涘缓琛ㄥ崟 */
-function handleStock(row: MesWmReturnSalesLineApi.ReturnSalesLine) {
- openDetailForm(row.id!, row.itemId);
-}
-
-/** 鎵撳紑涓婃灦鏄庣粏琛ㄥ崟 */
-function openDetailForm(lineId: number, itemId?: number, detailId?: number) {
- detailFormModalApi
- .setData({ detailId, itemId, lineId, returnId: props.returnId })
- .open();
-}
-
-/** 鑾峰彇宸插睍寮�琛岀殑涓婃灦鏄庣粏 */
-function getExpandedDetails(row: MesWmReturnSalesLineApi.ReturnSalesLine) {
- return detailMap[row.id!] || [];
-}
-
-/** 鍔犺浇鎸囧畾琛岀殑涓婃灦鏄庣粏 */
-async function loadLineDetails(lineId: number) {
- detailMap[lineId] = await getReturnSalesDetailListByLineId(lineId);
-}
-
-/** 灞曞紑琛屾椂鎳掑姞杞戒笂鏋舵槑缁� */
-async function handleExpandChange(
- row: MesWmReturnSalesLineApi.ReturnSalesLine,
- expanded: boolean,
-) {
- if (!expanded) {
- return;
- }
- await loadLineDetails(row.id!);
-}
-
-/** 鏄庣粏琛ㄥ崟鎻愪氦鎴愬姛鍚庯紝鍒锋柊瀵瑰簲琛屽凡灞曞紑鐨勬槑缁� */
-async function handleDetailSuccess(lineId: number) {
- await loadLineDetails(lineId);
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- gridOptions: {
- columns: useLineGridColumns(isEditable.value, isStock.value),
- expandConfig: {
- padding: true,
- },
- height: 400,
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }) => {
- if (!props.returnId) {
- return { list: [], total: 0 };
- }
- return await getReturnSalesLinePage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- returnId: props.returnId,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- },
- } as VxeTableGridOptions<MesWmReturnSalesLineApi.ReturnSalesLine>,
- gridEvents: {
- toggleRowExpand: ({
- expanded,
- row,
- }: {
- expanded: boolean;
- row: MesWmReturnSalesLineApi.ReturnSalesLine;
- }) => {
- handleExpandChange(row, expanded);
- },
- },
-});
-</script>
-
-<template>
- <div>
- <LineFormModal @success="handleRefresh" />
- <DetailFormModal @success="handleDetailSuccess" />
- <Grid table-title="鐗╂枡淇℃伅">
- <template v-if="isEditable" #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: '娣诲姞鐗╂枡',
- type: 'primary',
- icon: ACTION_ICON.ADD,
- onClick: handleCreate,
- },
- ]"
- />
- </template>
- <template #detail="{ row }">
- <DetailList
- :details="getExpandedDetails(row)"
- :form-type="formType"
- @edit="(detailId) => openDetailForm(row.id!, row.itemId, detailId)"
- @refresh="loadLineDetails(row.id!)"
- />
- </template>
- <template #actions="{ row }">
- <div class="flex items-center justify-center">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- ifShow: isEditable,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- ifShow: isEditable,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.itemName]),
- confirm: handleDelete.bind(null, row),
- },
- },
- {
- label: '涓婃灦',
- type: 'link',
- ifShow: isStock,
- onClick: handleStock.bind(null, row),
- },
- ]"
- />
- <PrinterLabel
- v-if="isStock"
- :biz-code="row.batchCode"
- :biz-id="row.batchId"
- biz-type="BATCH"
- />
- </div>
- </template>
- </Grid>
- </div>
-</template>
diff --git a/src/views/returnvendor/data.ts b/src/views/returnvendor/data.ts
deleted file mode 100644
index b1e5a25..0000000
--- a/src/views/returnvendor/data.ts
+++ /dev/null
@@ -1,530 +0,0 @@
-import type { VbenFormApi, VbenFormSchema } from '#/adapter/form';
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmMaterialStockApi } from '#/api/mes/wm/materialstock';
-import type { MesWmReturnVendorApi } from '#/api/mes/wm/returnvendor';
-import type { MesWmReturnVendorDetailApi } from '#/api/mes/wm/returnvendor/detail';
-import type { MesWmReturnVendorLineApi } from '#/api/mes/wm/returnvendor/line';
-
-import { h, markRaw } from 'vue';
-
-import { DICT_TYPE, MesAutoCodeRuleCode } from '@vben/constants';
-
-import { Button } from 'ant-design-vue';
-
-import { generateAutoCode } from '#/api/mes/md/autocode/record';
-import { MdItemSelect } from '#/views/mes/md/item/components';
-import { MdVendorSelect } from '#/views/mes/md/vendor/components';
-import { WmBatchSelect } from '#/views/wls/batch/components';
-import { WmMaterialStockSelect } from '#/views/wls/materialstock/components';
-import {
- WmWarehouseAreaSelect,
- WmWarehouseLocationSelect,
- WmWarehouseSelect,
-} from '#/views/wls/warehouse/components';
-
-/** 琛ㄥ崟绫诲瀷 */
-export type FormType = 'create' | 'detail' | 'finish' | 'stock' | 'update';
-
-/** 琛ㄥ崟澶撮儴鏄惁鍙锛堟嫞璐с�佽鎯呫�佸畬鎴愭�侊級 */
-function isHeaderReadonly(formType: FormType): boolean {
- return formType === 'detail' || formType === 'finish' || formType === 'stock';
-}
-
-/** 鏂板/淇敼鐨勮〃鍗� */
-export function useFormSchema(
- formType: FormType,
- formApi?: VbenFormApi,
-): VbenFormSchema[] {
- return [
- {
- fieldName: 'id',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'status',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'code',
- label: '閫�璐у崟缂栧彿',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ラ��璐у崟缂栧彿',
- },
- rules: 'required',
- suffix: isHeaderReadonly(formType)
- ? undefined
- : () =>
- h(
- Button,
- {
- type: 'default',
- onClick: async () => {
- const code = await generateAutoCode(
- MesAutoCodeRuleCode.WM_RETURN_VENDOR_CODE,
- );
- await formApi?.setFieldValue('code', code);
- },
- },
- { default: () => '鐢熸垚' },
- ),
- },
- {
- fieldName: 'name',
- label: '閫�璐у崟鍚嶇О',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ラ��璐у崟鍚嶇О',
- },
- rules: 'required',
- },
- {
- fieldName: 'purchaseOrderCode',
- label: '閲囪喘璁㈠崟鍙�',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ラ噰璐鍗曞彿',
- },
- },
- {
- fieldName: 'vendorId',
- label: '渚涘簲鍟�',
- component: markRaw(MdVendorSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨渚涘簲鍟�',
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'returnDate',
- label: '閫�璐ф棩鏈�',
- component: 'DatePicker',
- componentProps: {
- class: '!w-full',
- format: 'YYYY-MM-DD HH:mm:ss',
- placeholder: '璇烽�夋嫨閫�璐ф棩鏈�',
- showTime: true,
- valueFormat: 'x',
- },
- rules: 'required',
- },
- {
- fieldName: 'returnReason',
- label: '閫�璐у師鍥�',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- placeholder: '璇疯緭鍏ラ��璐у師鍥�',
- rows: 2,
- },
- },
- {
- fieldName: 'transportCode',
- label: '杩愬崟鍙�',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ヨ繍鍗曞彿',
- },
- },
- {
- fieldName: 'transportTelephone',
- label: '鑱旂郴鐢佃瘽',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ヨ仈绯荤數璇�',
- },
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勬悳绱㈣〃鍗� */
-export function useGridFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'code',
- label: '閫�璐у崟缂栧彿',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ラ��璐у崟缂栧彿',
- },
- },
- {
- fieldName: 'name',
- label: '閫�璐у崟鍚嶇О',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ラ��璐у崟鍚嶇О',
- },
- },
- {
- fieldName: 'purchaseOrderCode',
- label: '閲囪喘璁㈠崟缂栧彿',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ラ噰璐鍗曠紪鍙�',
- },
- },
- {
- fieldName: 'vendorId',
- label: '渚涘簲鍟�',
- component: markRaw(MdVendorSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨渚涘簲鍟�',
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勫瓧娈� */
-export function useGridColumns(): VxeTableGridOptions<MesWmReturnVendorApi.ReturnVendor>['columns'] {
- return [
- {
- field: 'code',
- title: '閫�璐у崟缂栧彿',
- minWidth: 160,
- slots: { default: 'code' },
- },
- {
- field: 'name',
- title: '閫�璐у崟鍚嶇О',
- minWidth: 150,
- },
- {
- field: 'purchaseOrderCode',
- title: '閲囪喘璁㈠崟鍙�',
- minWidth: 140,
- },
- {
- field: 'vendorCode',
- title: '渚涘簲鍟嗙紪鐮�',
- minWidth: 120,
- },
- {
- field: 'vendorName',
- title: '渚涘簲鍟嗗悕绉�',
- minWidth: 150,
- },
- {
- field: 'returnDate',
- title: '閫�璐ф棩鏈�',
- width: 180,
- formatter: 'formatDateTime',
- },
- {
- field: 'status',
- title: '鍗曟嵁鐘舵��',
- minWidth: 110,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_RETURN_VENDOR_STATUS },
- },
- },
- {
- title: '鎿嶄綔',
- width: 240,
- fixed: 'right',
- slots: { default: 'actions' },
- },
- ];
-}
-
-/** 閫�璐у崟琛屽瓙琛ㄧ殑瀛楁 */
-export function useLineGridColumns(
- editable: boolean,
- stockable: boolean,
-): VxeTableGridOptions<MesWmReturnVendorLineApi.ReturnVendorLine>['columns'] {
- return [
- {
- type: 'expand',
- width: 48,
- slots: { content: 'detail' },
- },
- {
- field: 'itemCode',
- title: '鐗╂枡缂栫爜',
- minWidth: 120,
- },
- {
- field: 'itemName',
- title: '鐗╂枡鍚嶇О',
- minWidth: 140,
- },
- {
- field: 'specification',
- title: '瑙勬牸鍨嬪彿',
- minWidth: 120,
- },
- {
- field: 'unitMeasureName',
- title: '鍗曚綅',
- width: 80,
- },
- {
- field: 'quantity',
- title: '閫�璐ф暟閲�',
- width: 100,
- },
- {
- field: 'batchCode',
- title: '鎵规鍙�',
- minWidth: 120,
- },
- ...(editable || stockable
- ? [
- {
- title: '鎿嶄綔',
- width: 160,
- fixed: 'right',
- slots: { default: 'actions' },
- } as const,
- ]
- : []),
- ];
-}
-
-/** 閫�璐у崟琛屾柊澧�/淇敼鐨勮〃鍗� */
-export function useLineFormSchema(
- vendorId?: number,
- formApi?: VbenFormApi,
-): VbenFormSchema[] {
- return [
- {
- fieldName: 'itemId',
- label: '浜у搧鐗╂枡',
- component: markRaw(MdItemSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨浜у搧鐗╂枡',
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'quantity',
- label: '閫�璐ф暟閲�',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0,
- placeholder: '璇疯緭鍏ラ��璐ф暟閲�',
- precision: 2,
- },
- rules: 'required',
- },
- {
- fieldName: 'batchId',
- label: '鎵规鍙�',
- component: markRaw(WmBatchSelect),
- componentProps: {
- // 閫夋嫨鎵规鍚庡悓姝ユ壒娆″彿
- onChange: async (batch?: { code?: string }) => {
- await formApi?.setFieldValue('batchCode', batch?.code);
- },
- vendorId,
- },
- dependencies: {
- triggerFields: ['itemId'],
- componentProps: (values) => ({
- itemId: values.itemId,
- vendorId,
- }),
- },
- },
- {
- fieldName: 'batchCode',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
-
-/** 鎷h揣鏄庣粏瀛愯〃鐨勫瓧娈� */
-export function useDetailGridColumns(
- stockable: boolean,
-): VxeTableGridOptions<MesWmReturnVendorDetailApi.ReturnVendorDetail>['columns'] {
- return [
- {
- field: 'batchCode',
- title: '鎵规鍙�',
- minWidth: 120,
- },
- {
- field: 'warehouseName',
- title: '浠撳簱鍚嶇О',
- minWidth: 100,
- },
- {
- field: 'locationName',
- title: '搴撳尯鍚嶇О',
- minWidth: 100,
- },
- {
- field: 'areaName',
- title: '搴撲綅鍚嶇О',
- minWidth: 100,
- },
- {
- field: 'quantity',
- title: '鏁伴噺',
- width: 100,
- },
- ...(stockable
- ? [
- {
- title: '鎿嶄綔',
- width: 120,
- fixed: 'right',
- slots: { default: 'actions' },
- } as const,
- ]
- : []),
- ];
-}
-
-/** 鎷h揣鏄庣粏鏂板/淇敼鐨勮〃鍗� */
-export function useDetailFormSchema(formApi?: VbenFormApi): VbenFormSchema[] {
- return [
- {
- fieldName: 'quantityMax',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'itemId',
- label: '鐗╂枡',
- component: markRaw(MdItemSelect),
- componentProps: {
- disabled: true,
- },
- },
- {
- fieldName: 'materialStockId',
- label: '搴撳瓨璁板綍',
- component: markRaw(WmMaterialStockSelect),
- componentProps: {
- // 閫夋嫨搴撳瓨璁板綍鍚庯紝鑷姩鍥炲~浠撳簱/搴撳尯/搴撲綅/鎵规/鏁伴噺
- onChange: async (stock?: MesWmMaterialStockApi.MaterialStock) => {
- await formApi?.setValues({
- areaId: stock?.areaId,
- batchCode: stock?.batchCode,
- batchId: stock?.batchId,
- locationId: stock?.locationId,
- quantity: stock?.quantity,
- quantityMax: stock?.quantity,
- warehouseId: stock?.warehouseId,
- });
- },
- },
- rules: 'selectRequired',
- dependencies: {
- triggerFields: ['itemId'],
- componentProps: (values) => ({
- itemId: values.itemId,
- }),
- },
- },
- {
- fieldName: 'quantity',
- label: '鏁伴噺',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0,
- placeholder: '璇疯緭鍏ユ暟閲�',
- precision: 2,
- },
- rules: 'required',
- dependencies: {
- triggerFields: ['quantityMax'],
- componentProps: (values) => ({
- class: '!w-full',
- max: values.quantityMax,
- min: 0,
- placeholder: '璇疯緭鍏ユ暟閲�',
- precision: 2,
- }),
- },
- },
- {
- fieldName: 'warehouseId',
- label: '浠撳簱',
- component: markRaw(WmWarehouseSelect),
- componentProps: {
- disabled: true,
- },
- },
- {
- fieldName: 'locationId',
- label: '搴撳尯',
- component: markRaw(WmWarehouseLocationSelect),
- componentProps: {
- disabled: true,
- },
- dependencies: {
- triggerFields: ['warehouseId'],
- componentProps: (values) => ({
- disabled: true,
- warehouseId: values.warehouseId,
- }),
- },
- },
- {
- fieldName: 'areaId',
- label: '搴撲綅',
- component: markRaw(WmWarehouseAreaSelect),
- componentProps: {
- disabled: true,
- },
- dependencies: {
- triggerFields: ['locationId'],
- componentProps: (values) => ({
- disabled: true,
- locationId: values.locationId,
- }),
- },
- },
- {
- fieldName: 'batchCode',
- label: '鎵规鍙�',
- component: 'Input',
- componentProps: {
- disabled: true,
- },
- },
- ];
-}
diff --git a/src/views/returnvendor/index.vue b/src/views/returnvendor/index.vue
deleted file mode 100644
index 895e494..0000000
--- a/src/views/returnvendor/index.vue
+++ /dev/null
@@ -1,201 +0,0 @@
-<script lang="ts" setup>
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmReturnVendorApi } from '#/api/mes/wm/returnvendor';
-
-import { Page, useVbenModal } from '@vben/common-ui';
-import { MesWmReturnVendorStatusEnum } from '@vben/constants';
-import { downloadFileFromBlobPart } from '@vben/utils';
-
-import { Button, message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import {
- cancelReturnVendor,
- deleteReturnVendor,
- exportReturnVendor,
- getReturnVendorPage,
-} from '#/api/mes/wm/returnvendor';
-import { $t } from '#/locales';
-
-import { useGridColumns, useGridFormSchema } from './data';
-import Form from './modules/form.vue';
-
-const [FormModal, formModalApi] = useVbenModal({
- connectedComponent: Form,
- destroyOnClose: true,
-});
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- gridApi.query();
-}
-
-/** 鍒涘缓渚涘簲鍟嗛��璐у崟 */
-function handleCreate() {
- formModalApi.setData({ formType: 'create' }).open();
-}
-
-/** 鏌ョ湅渚涘簲鍟嗛��璐у崟 */
-function handleDetail(row: MesWmReturnVendorApi.ReturnVendor) {
- formModalApi.setData({ formType: 'detail', id: row.id }).open();
-}
-
-/** 缂栬緫渚涘簲鍟嗛��璐у崟 */
-function handleEdit(row: MesWmReturnVendorApi.ReturnVendor) {
- formModalApi.setData({ formType: 'update', id: row.id }).open();
-}
-
-/** 鎵ц鎷h揣 */
-function handleStock(row: MesWmReturnVendorApi.ReturnVendor) {
- formModalApi.setData({ formType: 'stock', id: row.id }).open();
-}
-
-/** 瀹屾垚閫�璐� */
-function handleFinish(row: MesWmReturnVendorApi.ReturnVendor) {
- formModalApi.setData({ formType: 'finish', id: row.id }).open();
-}
-
-/** 鍒犻櫎渚涘簲鍟嗛��璐у崟 */
-async function handleDelete(row: MesWmReturnVendorApi.ReturnVendor) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.code]),
- duration: 0,
- });
- try {
- await deleteReturnVendor(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.code]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-/** 鍙栨秷渚涘簲鍟嗛��璐у崟 */
-async function handleCancel(row: MesWmReturnVendorApi.ReturnVendor) {
- await cancelReturnVendor(row.id!);
- message.success('鍙栨秷鎴愬姛');
- handleRefresh();
-}
-
-/** 瀵煎嚭琛ㄦ牸 */
-async function handleExport() {
- const data = await exportReturnVendor(await gridApi.formApi.getValues());
- downloadFileFromBlobPart({ fileName: '渚涘簲鍟嗛��璐у崟.xls', source: data });
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- formOptions: {
- schema: useGridFormSchema(),
- },
- gridOptions: {
- columns: useGridColumns(),
- height: 'auto',
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }, formValues) => {
- return await getReturnVendorPage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- ...formValues,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- search: true,
- },
- } as VxeTableGridOptions<MesWmReturnVendorApi.ReturnVendor>,
-});
-</script>
-
-<template>
- <Page auto-content-height><FormModal @success="handleRefresh" />
-
- <Grid table-title="渚涘簲鍟嗛��璐у崟鍒楄〃">
- <template #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: $t('ui.actionTitle.create', ['渚涘簲鍟嗛��璐у崟']),
- type: 'primary',
- icon: ACTION_ICON.ADD,
- auth: ['mes:wm-return-vendor:create'],
- onClick: handleCreate,
- },
- {
- label: $t('ui.actionTitle.export'),
- type: 'primary',
- icon: ACTION_ICON.DOWNLOAD,
- auth: ['mes:wm-return-vendor:export'],
- onClick: handleExport,
- },
- ]"
- />
- </template>
- <template #code="{ row }">
- <Button type="link" @click="handleDetail(row)">
- {{ row.code }}
- </Button>
- </template>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- auth: ['mes:wm-return-vendor:update'],
- ifShow: row.status === MesWmReturnVendorStatusEnum.PREPARE,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- auth: ['mes:wm-return-vendor:delete'],
- ifShow: row.status === MesWmReturnVendorStatusEnum.PREPARE,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.code]),
- confirm: handleDelete.bind(null, row),
- },
- },
- {
- label: '鎵ц鎷h揣',
- type: 'link',
- auth: ['mes:wm-return-vendor:update'],
- ifShow: row.status === MesWmReturnVendorStatusEnum.APPROVING,
- onClick: handleStock.bind(null, row),
- },
- {
- label: '瀹屾垚閫�璐�',
- type: 'link',
- auth: ['mes:wm-return-vendor:update-status'],
- ifShow: row.status === MesWmReturnVendorStatusEnum.APPROVED,
- onClick: handleFinish.bind(null, row),
- },
- {
- label: '鍙栨秷',
- type: 'link',
- danger: true,
- auth: ['mes:wm-return-vendor:update'],
- ifShow:
- row.status === MesWmReturnVendorStatusEnum.APPROVING ||
- row.status === MesWmReturnVendorStatusEnum.APPROVED,
- popConfirm: {
- title: '纭鍙栨秷璇ヤ緵搴斿晢閫�璐у崟锛熷彇娑堝悗涓嶅彲鎭㈠銆�',
- confirm: handleCancel.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </Page>
-</template>
diff --git a/src/views/returnvendor/modules/detail-form.vue b/src/views/returnvendor/modules/detail-form.vue
deleted file mode 100644
index f4a2788..0000000
--- a/src/views/returnvendor/modules/detail-form.vue
+++ /dev/null
@@ -1,104 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmReturnVendorDetailApi } from '#/api/mes/wm/returnvendor/detail';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createReturnVendorDetail,
- getReturnVendorDetail,
- updateReturnVendorDetail,
-} from '#/api/mes/wm/returnvendor/detail';
-import { $t } from '#/locales';
-
-import { useDetailFormSchema } from '../data';
-
-const emit = defineEmits<{ success: [lineId: number] }>();
-const formData = ref<MesWmReturnVendorDetailApi.ReturnVendorDetail>();
-const returnId = ref<number>(); // 鎵�灞為��璐у崟缂栧彿
-const lineId = ref<number>(); // 鎵�灞為��璐у崟琛岀紪鍙�
-
-const getTitle = computed(() => {
- return formData.value?.id
- ? $t('ui.actionTitle.edit', ['鎷h揣鏄庣粏'])
- : $t('ui.actionTitle.create', ['鎷h揣鏄庣粏']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 90,
- },
- layout: 'horizontal',
- schema: useDetailFormSchema(),
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data =
- (await formApi.getValues()) as MesWmReturnVendorDetailApi.ReturnVendorDetail;
- data.returnId = returnId.value;
- data.lineId = lineId.value;
- try {
- await (formData.value?.id
- ? updateReturnVendorDetail({ ...data, id: formData.value.id })
- : createReturnVendorDetail(data));
- // 鍏抽棴骞舵彁绀�
- await modalApi.close();
- emit('success', lineId.value!);
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- return;
- }
- formApi.setState({ schema: useDetailFormSchema(formApi) });
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{
- detailId?: number;
- itemId?: number;
- lineId: number;
- returnId: number;
- }>();
- returnId.value = data.returnId;
- lineId.value = data.lineId;
- if (data.detailId) {
- modalApi.lock();
- try {
- formData.value = await getReturnVendorDetail(data.detailId);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- } else if (data.itemId) {
- await formApi.setFieldValue('itemId', data.itemId);
- }
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- </Modal>
-</template>
diff --git a/src/views/returnvendor/modules/detail-list.vue b/src/views/returnvendor/modules/detail-list.vue
deleted file mode 100644
index 7ff080c..0000000
--- a/src/views/returnvendor/modules/detail-list.vue
+++ /dev/null
@@ -1,105 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmReturnVendorDetailApi } from '#/api/mes/wm/returnvendor/detail';
-
-import { computed, watch } from 'vue';
-
-import { message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import { deleteReturnVendorDetail } from '#/api/mes/wm/returnvendor/detail';
-import { $t } from '#/locales';
-
-import { useDetailGridColumns } from '../data';
-
-const props = defineProps<{
- details: MesWmReturnVendorDetailApi.ReturnVendorDetail[];
- formType: FormType;
-}>();
-
-const emit = defineEmits<{
- edit: [detailId: number];
- refresh: [];
-}>();
-
-const isStock = computed(() => props.formType === 'stock'); // 鏄惁涓烘嫞璐фā寮�
-
-/** 缂栬緫鎷h揣鏄庣粏 */
-function handleEdit(row: MesWmReturnVendorDetailApi.ReturnVendorDetail) {
- emit('edit', row.id!);
-}
-
-/** 鍒犻櫎鎷h揣鏄庣粏 */
-async function handleDelete(
- row: MesWmReturnVendorDetailApi.ReturnVendorDetail,
-) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.warehouseName]),
- duration: 0,
- });
- try {
- await deleteReturnVendorDetail(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.warehouseName]));
- emit('refresh');
- } finally {
- hideLoading();
- }
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- gridOptions: {
- border: true,
- columns: useDetailGridColumns(isStock.value),
- data: props.details,
- pagerConfig: {
- enabled: false,
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- size: 'small',
- toolbarConfig: {
- enabled: false,
- },
- } as VxeTableGridOptions<MesWmReturnVendorDetailApi.ReturnVendorDetail>,
-});
-
-watch(
- () => props.details,
- (details) => gridApi.setGridOptions({ data: details }),
-);
-</script>
-
-<template>
- <div class="px-4 py-2">
- <Grid>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [
- row.warehouseName,
- ]),
- confirm: handleDelete.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </div>
-</template>
diff --git a/src/views/returnvendor/modules/form.vue b/src/views/returnvendor/modules/form.vue
deleted file mode 100644
index 8890852..0000000
--- a/src/views/returnvendor/modules/form.vue
+++ /dev/null
@@ -1,236 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { MesWmReturnVendorApi } from '#/api/mes/wm/returnvendor';
-
-import { computed, ref } from 'vue';
-
-import { confirm, useVbenModal } from '@vben/common-ui';
-import { MesWmReturnVendorStatusEnum } from '@vben/constants';
-
-import { Button, Divider, message, Popconfirm } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- checkReturnVendorQuantity,
- createReturnVendor,
- finishReturnVendor,
- getReturnVendor,
- stockReturnVendor,
- submitReturnVendor,
- updateReturnVendor,
-} from '#/api/mes/wm/returnvendor';
-import { $t } from '#/locales';
-
-import { useFormSchema } from '../data';
-import LineList from './line-list.vue';
-
-const emit = defineEmits(['success']);
-const formType = ref<FormType>('create');
-const formData = ref<MesWmReturnVendorApi.ReturnVendor>();
-const originalSnapshot = ref(''); // 琛ㄥ崟鍘熷鏁版嵁蹇収锛岀敤浜庢彁浜ゆ椂璺宠繃鏈彉鏇寸殑淇濆瓨璇锋眰
-const isEditable = computed(() =>
- // 鏄惁涓虹紪杈戞ā寮忥紙鍙繚瀛橈級
- ['create', 'update'].includes(formType.value),
-);
-const isStock = computed(() => formType.value === 'stock'); // 鏄惁涓烘嫞璐фā寮�
-const isFinish = computed(() => formType.value === 'finish'); // 鏄惁涓哄畬鎴愰��璐фā寮�
-const canSubmit = computed(
- () =>
- // 鏄惁鍙彁浜�
- formType.value === 'update' &&
- formData.value?.status === MesWmReturnVendorStatusEnum.PREPARE,
-);
-const getTitle = computed(() => {
- if (formType.value === 'detail') {
- return $t('ui.actionTitle.view', ['渚涘簲鍟嗛��璐у崟']);
- }
- if (formType.value === 'stock') {
- return '鎵ц鎷h揣';
- }
- if (formType.value === 'finish') {
- return '瀹屾垚閫�璐�';
- }
- return formType.value === 'update'
- ? $t('ui.actionTitle.edit', ['渚涘簲鍟嗛��璐у崟'])
- : $t('ui.actionTitle.create', ['渚涘簲鍟嗛��璐у崟']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 110,
- },
- layout: 'horizontal',
- schema: [],
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-/** 鎻愪氦閫�璐у崟锛氳〃鍗曟湁淇敼鏃跺厛淇濆瓨锛屽啀璋冪敤鎻愪氦鎺ュ彛 */
-async function handleSubmit() {
- const { valid } = await formApi.validate();
- if (!valid || !formData.value?.id) {
- return;
- }
- modalApi.lock();
- try {
- const current = JSON.stringify(await formApi.getValues());
- if (current !== originalSnapshot.value) {
- const data =
- (await formApi.getValues()) as MesWmReturnVendorApi.ReturnVendor;
- await updateReturnVendor({ ...formData.value, ...data });
- originalSnapshot.value = current;
- }
- await submitReturnVendor(formData.value.id);
- message.success('鎻愪氦鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-/** 鎵ц鎷h揣锛氭嫞璐ф暟閲忎笌閫�璐ф暟閲忎笉涓�鑷存椂浜屾纭 */
-async function handleStock() {
- if (!formData.value?.id) {
- return;
- }
- const quantityMatch = await checkReturnVendorQuantity(formData.value.id);
- if (!quantityMatch) {
- try {
- await confirm('閫�璐ф暟閲忎笌鎷h揣鏁伴噺涓嶄竴鑷达紝纭鎵ц鎷h揣锛�');
- } catch {
- return;
- }
- }
- modalApi.lock();
- try {
- await stockReturnVendor(formData.value.id);
- message.success('鎷h揣鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-/** 瀹屾垚閫�璐� */
-async function handleFinish() {
- if (!formData.value?.id) {
- return;
- }
- modalApi.lock();
- try {
- await finishReturnVendor(formData.value.id);
- message.success('瀹屾垚鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- if (!isEditable.value) {
- await modalApi.close();
- return;
- }
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data =
- (await formApi.getValues()) as MesWmReturnVendorApi.ReturnVendor;
- try {
- if (formData.value?.id) {
- await updateReturnVendor({ ...formData.value, ...data });
- formData.value = { ...formData.value, ...data };
- } else {
- const id = await createReturnVendor(data);
- formData.value = {
- ...data,
- id,
- status: MesWmReturnVendorStatusEnum.PREPARE,
- };
- await formApi.setFieldValue('id', id);
- await formApi.setFieldValue('status', formData.value.status);
- formType.value = 'update';
- }
- originalSnapshot.value = JSON.stringify(await formApi.getValues());
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- originalSnapshot.value = '';
- return;
- }
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{ formType: FormType; id?: number }>();
- formType.value = data.formType;
- formApi.setState({ schema: useFormSchema(formType.value, formApi) });
- formApi.setDisabled(!isEditable.value);
- modalApi.setState({ showConfirmButton: isEditable.value });
- if (data?.id) {
- modalApi.lock();
- try {
- formData.value = await getReturnVendor(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- }
- originalSnapshot.value = JSON.stringify(await formApi.getValues());
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- <!-- 闈炴柊寤烘ā寮忓睍绀虹墿鏂欎俊鎭� -->
- <template v-if="formData?.id">
- <Divider>鐗╂枡淇℃伅</Divider>
- <div class="mx-4">
- <LineList
- :form-type="formType"
- :return-id="formData.id"
- :vendor-id="formData.vendorId"
- />
- </div>
- </template>
- <template #prepend-footer>
- <div class="flex flex-auto items-center gap-2">
- <Popconfirm
- v-if="canSubmit"
- title="纭鎻愪氦璇ラ��璐у崟锛熴�愭彁浜ゅ悗灏嗕笉鑳戒慨鏀广��"
- @confirm="handleSubmit"
- >
- <Button type="primary">鎻愪氦</Button>
- </Popconfirm>
- <Button v-if="isStock" type="primary" @click="handleStock">
- 鎵ц鎷h揣
- </Button>
- <Popconfirm
- v-if="isFinish"
- title="纭瀹屾垚璇ラ��璐у崟骞舵墽琛岄��璐э紵"
- @confirm="handleFinish"
- >
- <Button type="primary">瀹屾垚閫�璐�</Button>
- </Popconfirm>
- </div>
- </template>
- </Modal>
-</template>
diff --git a/src/views/returnvendor/modules/line-form.vue b/src/views/returnvendor/modules/line-form.vue
deleted file mode 100644
index a7bf7a6..0000000
--- a/src/views/returnvendor/modules/line-form.vue
+++ /dev/null
@@ -1,99 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmReturnVendorLineApi } from '#/api/mes/wm/returnvendor/line';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createReturnVendorLine,
- getReturnVendorLine,
- updateReturnVendorLine,
-} from '#/api/mes/wm/returnvendor/line';
-import { $t } from '#/locales';
-
-import { useLineFormSchema } from '../data';
-
-const emit = defineEmits(['success']);
-const formData = ref<MesWmReturnVendorLineApi.ReturnVendorLine>();
-const returnId = ref<number>(); // 鎵�灞為��璐у崟缂栧彿
-
-const getTitle = computed(() => {
- return formData.value?.id
- ? $t('ui.actionTitle.edit', ['渚涘簲鍟嗛��璐у崟琛�'])
- : $t('ui.actionTitle.create', ['渚涘簲鍟嗛��璐у崟琛�']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 90,
- },
- layout: 'horizontal',
- schema: [],
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data =
- (await formApi.getValues()) as MesWmReturnVendorLineApi.ReturnVendorLine;
- data.returnId = returnId.value;
- try {
- await (formData.value?.id
- ? updateReturnVendorLine({ ...data, id: formData.value.id })
- : createReturnVendorLine(data));
- // 鍏抽棴骞舵彁绀�
- await modalApi.close();
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- return;
- }
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{
- id?: number;
- returnId: number;
- vendorId?: number;
- }>();
- returnId.value = data.returnId;
- formApi.setState({ schema: useLineFormSchema(data.vendorId, formApi) });
- if (!data.id) {
- return;
- }
- modalApi.lock();
- try {
- formData.value = await getReturnVendorLine(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- </Modal>
-</template>
diff --git a/src/views/returnvendor/modules/line-list.vue b/src/views/returnvendor/modules/line-list.vue
deleted file mode 100644
index 7f67f49..0000000
--- a/src/views/returnvendor/modules/line-list.vue
+++ /dev/null
@@ -1,237 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmReturnVendorDetailApi } from '#/api/mes/wm/returnvendor/detail';
-import type { MesWmReturnVendorLineApi } from '#/api/mes/wm/returnvendor/line';
-
-import { computed, reactive } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import { getReturnVendorDetailListByLineId } from '#/api/mes/wm/returnvendor/detail';
-import {
- deleteReturnVendorLine,
- getReturnVendorLinePage,
-} from '#/api/mes/wm/returnvendor/line';
-import { $t } from '#/locales';
-import { PrinterLabel } from '#/views/wls/barcode/components';
-
-import { useLineGridColumns } from '../data';
-import DetailForm from './detail-form.vue';
-import DetailList from './detail-list.vue';
-import LineForm from './line-form.vue';
-
-const props = defineProps<{
- formType: FormType;
- returnId: number;
- vendorId?: number;
-}>();
-
-const isEditable = computed(() =>
- // 鏄惁鍙紪杈戞槑缁嗚
- ['create', 'update'].includes(props.formType),
-);
-const isStock = computed(() => props.formType === 'stock'); // 鏄惁涓烘嫞璐фā寮�
-const detailMap = reactive<
- Record<number, MesWmReturnVendorDetailApi.ReturnVendorDetail[]>
->({}); // 宸插睍寮�琛岀殑鎷h揣鏄庣粏缂撳瓨
-
-const [LineFormModal, lineFormModalApi] = useVbenModal({
- connectedComponent: LineForm,
- destroyOnClose: true,
-});
-
-const [DetailFormModal, detailFormModalApi] = useVbenModal({
- connectedComponent: DetailForm,
- destroyOnClose: true,
-});
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- for (const id of Object.keys(detailMap)) {
- delete detailMap[Number(id)];
- }
- gridApi.query();
-}
-
-/** 娣诲姞鐗╂枡 */
-function handleCreate() {
- lineFormModalApi
- .setData({ returnId: props.returnId, vendorId: props.vendorId })
- .open();
-}
-
-/** 缂栬緫鐗╂枡 */
-function handleEdit(row: MesWmReturnVendorLineApi.ReturnVendorLine) {
- lineFormModalApi
- .setData({ id: row.id, returnId: props.returnId, vendorId: props.vendorId })
- .open();
-}
-
-/** 鍒犻櫎鐗╂枡 */
-async function handleDelete(row: MesWmReturnVendorLineApi.ReturnVendorLine) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.itemName]),
- duration: 0,
- });
- try {
- await deleteReturnVendorLine(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.itemName]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-/** 鎷h揣锛氱洿鎺ユ墦寮�鏄庣粏鍒涘缓琛ㄥ崟 */
-function handlePicking(row: MesWmReturnVendorLineApi.ReturnVendorLine) {
- openDetailForm(row.id!, row.itemId);
-}
-
-/** 鎵撳紑鎷h揣鏄庣粏琛ㄥ崟 */
-function openDetailForm(lineId: number, itemId?: number, detailId?: number) {
- detailFormModalApi
- .setData({ detailId, itemId, lineId, returnId: props.returnId })
- .open();
-}
-
-/** 鑾峰彇宸插睍寮�琛岀殑鎷h揣鏄庣粏 */
-function getExpandedDetails(row: MesWmReturnVendorLineApi.ReturnVendorLine) {
- return detailMap[row.id!] || [];
-}
-
-/** 鍔犺浇鎸囧畾琛岀殑鎷h揣鏄庣粏 */
-async function loadLineDetails(lineId: number) {
- detailMap[lineId] = await getReturnVendorDetailListByLineId(lineId);
-}
-
-/** 灞曞紑琛屾椂鎳掑姞杞芥嫞璐ф槑缁� */
-async function handleExpandChange(
- row: MesWmReturnVendorLineApi.ReturnVendorLine,
- expanded: boolean,
-) {
- if (!expanded) {
- return;
- }
- await loadLineDetails(row.id!);
-}
-
-/** 鏄庣粏琛ㄥ崟鎻愪氦鎴愬姛鍚庯紝鍒锋柊瀵瑰簲琛屽凡灞曞紑鐨勬槑缁� */
-async function handleDetailSuccess(lineId: number) {
- await loadLineDetails(lineId);
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- gridOptions: {
- columns: useLineGridColumns(isEditable.value, isStock.value),
- expandConfig: {
- padding: true,
- },
- height: 400,
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }) => {
- if (!props.returnId) {
- return { list: [], total: 0 };
- }
- return await getReturnVendorLinePage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- returnId: props.returnId,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- },
- } as VxeTableGridOptions<MesWmReturnVendorLineApi.ReturnVendorLine>,
- gridEvents: {
- toggleRowExpand: ({
- expanded,
- row,
- }: {
- expanded: boolean;
- row: MesWmReturnVendorLineApi.ReturnVendorLine;
- }) => {
- handleExpandChange(row, expanded);
- },
- },
-});
-</script>
-
-<template>
- <div>
- <LineFormModal @success="handleRefresh" />
- <DetailFormModal @success="handleDetailSuccess" />
- <Grid table-title="鐗╂枡淇℃伅">
- <template v-if="isEditable" #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: '娣诲姞鐗╂枡',
- type: 'primary',
- icon: ACTION_ICON.ADD,
- onClick: handleCreate,
- },
- ]"
- />
- </template>
- <template #detail="{ row }">
- <DetailList
- :details="getExpandedDetails(row)"
- :form-type="formType"
- @edit="(detailId) => openDetailForm(row.id!, row.itemId, detailId)"
- @refresh="loadLineDetails(row.id!)"
- />
- </template>
- <template #actions="{ row }">
- <div class="flex items-center justify-center">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- ifShow: isEditable,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- ifShow: isEditable,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.itemName]),
- confirm: handleDelete.bind(null, row),
- },
- },
- {
- label: '鎷h揣',
- type: 'link',
- ifShow: isStock,
- onClick: handlePicking.bind(null, row),
- },
- ]"
- />
- <PrinterLabel
- v-if="isStock"
- :biz-code="row.batchCode"
- :biz-id="row.batchId"
- biz-type="BATCH"
- />
- </div>
- </template>
- </Grid>
- </div>
-</template>
diff --git a/src/views/salesnotice/components/index.ts b/src/views/salesnotice/components/index.ts
deleted file mode 100644
index 2bc67d6..0000000
--- a/src/views/salesnotice/components/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export { default as WmSalesNoticeLineSelect } from './line-select.vue';
-export { default as WmSalesNoticeSelect } from './select.vue';
diff --git a/src/views/salesnotice/components/line-select-dialog.vue b/src/views/salesnotice/components/line-select-dialog.vue
deleted file mode 100644
index fdd4c69..0000000
--- a/src/views/salesnotice/components/line-select-dialog.vue
+++ /dev/null
@@ -1,198 +0,0 @@
-<script lang="ts" setup>
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmSalesNoticeLineApi } from '#/api/mes/wm/salesnotice/line';
-
-import { nextTick, ref } from 'vue';
-
-import { DICT_TYPE } from '@vben/constants';
-
-import { message, Modal } from 'ant-design-vue';
-
-import { useVbenVxeGrid } from '#/adapter/vxe-table';
-import { getSalesNoticeLinePage } from '#/api/mes/wm/salesnotice/line';
-
-const emit = defineEmits<{
- selected: [rows: MesWmSalesNoticeLineApi.SalesNoticeLine[]];
-}>();
-
-const open = ref(false); // 寮圭獥鏄惁鎵撳紑
-const noticeId = ref<number>(); // 鎵�灞為�氱煡鍗曠紪鍙�
-const syncingSingleSelection = ref(false); // 鏄惁鍚屾鍗曢�夊嬀閫夌姸鎬�
-const selectedRows = ref<MesWmSalesNoticeLineApi.SalesNoticeLine[]>([]); // 宸查�夎鍒楄〃
-const preSelectedIds = ref<number[]>([]); // 棰勯�夎缂栧彿鍒楄〃
-
-/** 琛ㄦ牸瀛楁 */
-function useGridColumns(): VxeTableGridOptions<MesWmSalesNoticeLineApi.SalesNoticeLine>['columns'] {
- return [
- {
- type: 'checkbox',
- width: 50,
- },
- {
- field: 'itemCode',
- title: '鐗╂枡缂栫爜',
- minWidth: 120,
- },
- {
- field: 'itemName',
- title: '鐗╂枡鍚嶇О',
- minWidth: 140,
- },
- {
- field: 'specification',
- title: '瑙勬牸鍨嬪彿',
- minWidth: 120,
- },
- {
- field: 'unitMeasureName',
- title: '鍗曚綅',
- width: 80,
- },
- {
- field: 'quantity',
- title: '鍙戣揣鏁伴噺',
- width: 100,
- },
- {
- field: 'batchCode',
- title: '鎵规鍙�',
- minWidth: 120,
- },
- {
- field: 'oqcCheckFlag',
- title: '鏄惁妫�楠�',
- width: 90,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.INFRA_BOOLEAN_STRING },
- },
- },
- ];
-}
-
-/** 鍗曢�夋ā寮忎笅鍚屾 VXE 鍕鹃�夌姸鎬� */
-async function syncSingleSelection(
- row?: MesWmSalesNoticeLineApi.SalesNoticeLine,
-) {
- syncingSingleSelection.value = true;
- await nextTick();
- await gridApi.grid.clearCheckboxRow();
- if (row) {
- await gridApi.grid.setCheckboxRow(row, true);
- }
- await nextTick();
- syncingSingleSelection.value = false;
-}
-
-/** 澶勭悊鍕鹃�夊彉鍖栵紝鍙繚鐣欐渶鍚庝竴鏉� */
-async function handleCheckboxChange({
- checked,
- row,
-}: {
- checked: boolean;
- row?: MesWmSalesNoticeLineApi.SalesNoticeLine;
-}) {
- if (syncingSingleSelection.value) {
- return;
- }
- const selected = checked && row ? [row] : [];
- selectedRows.value = selected;
- await syncSingleSelection(selected[0]);
-}
-
-/** 鍥炴樉棰勯�夎 */
-function applyPreSelection() {
- if (preSelectedIds.value.length === 0) {
- return;
- }
- const rows =
- gridApi.grid.getData() as MesWmSalesNoticeLineApi.SalesNoticeLine[];
- for (const row of rows) {
- if (row.id && preSelectedIds.value.includes(row.id)) {
- gridApi.grid.setCheckboxRow(row, true);
- selectedRows.value = [row];
- }
- }
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- gridOptions: {
- columns: useGridColumns(),
- height: 460,
- keepSource: true,
- checkboxConfig: {
- highlight: true,
- reserve: true,
- },
- proxyConfig: {
- ajax: {
- query: async ({ page }) => {
- if (!noticeId.value) {
- return { list: [], total: 0 };
- }
- return await getSalesNoticeLinePage({
- noticeId: noticeId.value,
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- },
- } as VxeTableGridOptions<MesWmSalesNoticeLineApi.SalesNoticeLine>,
- gridEvents: {
- checkboxChange: handleCheckboxChange,
- },
-});
-
-/** 鎵撳紑琛岄�夋嫨寮圭獥 */
-async function openModal(id: number | undefined, selectedIds?: number[]) {
- open.value = true;
- noticeId.value = id;
- preSelectedIds.value = selectedIds || [];
- selectedRows.value = [];
- await nextTick();
- await gridApi.grid.clearCheckboxRow();
- await gridApi.query();
- await nextTick();
- applyPreSelection();
-}
-
-/** 鍏抽棴寮圭獥 */
-async function closeModal() {
- open.value = false;
- selectedRows.value = [];
- await gridApi.grid.clearCheckboxRow();
-}
-
-/** 纭閫夋嫨琛� */
-function handleConfirm() {
- if (selectedRows.value.length === 0) {
- message.warning('璇烽�夋嫨涓�鏉℃暟鎹�');
- return;
- }
- emit('selected', [selectedRows.value[0]!]);
- open.value = false;
-}
-
-defineExpose({ open: openModal });
-</script>
-
-<template>
- <Modal
- v-model:open="open"
- title="鍙戣揣閫氱煡鍗曡閫夋嫨"
- width="70%"
- :destroy-on-close="true"
- @cancel="closeModal"
- @ok="handleConfirm"
- >
- <Grid table-title="鍙戣揣閫氱煡鍗曡鍒楄〃" />
- </Modal>
-</template>
diff --git a/src/views/salesnotice/components/line-select.vue b/src/views/salesnotice/components/line-select.vue
deleted file mode 100644
index 990b972..0000000
--- a/src/views/salesnotice/components/line-select.vue
+++ /dev/null
@@ -1,153 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmSalesNoticeLineApi } from '#/api/mes/wm/salesnotice/line';
-
-import { computed, ref, useAttrs, watch } from 'vue';
-
-import { IconifyIcon } from '@vben/icons';
-
-import { Input, Tooltip } from 'ant-design-vue';
-
-import { getSalesNoticeLine } from '#/api/mes/wm/salesnotice/line';
-
-import WmSalesNoticeLineSelectDialog from './line-select-dialog.vue';
-
-defineOptions({ name: 'WmSalesNoticeLineSelect', inheritAttrs: false });
-
-const props = withDefaults(
- defineProps<{
- allowClear?: boolean;
- disabled?: boolean;
- modelValue?: number;
- noticeId?: number; // 鎵�灞炲彂璐ч�氱煡鍗曠紪鍙�
- placeholder?: string;
- }>(),
- {
- allowClear: true,
- disabled: false,
- modelValue: undefined,
- noticeId: undefined,
- placeholder: '璇烽�夋嫨鍙戣揣閫氱煡鍗曡',
- },
-);
-
-const emit = defineEmits<{
- change: [item: MesWmSalesNoticeLineApi.SalesNoticeLine | undefined];
- 'update:modelValue': [value: number | undefined];
-}>();
-
-const attrs = useAttrs();
-const dialogRef = ref<InstanceType<typeof WmSalesNoticeLineSelectDialog>>();
-const hovering = ref(false);
-const selectedItem = ref<MesWmSalesNoticeLineApi.SalesNoticeLine>();
-
-const displayLabel = computed(() => {
- const item = selectedItem.value;
- if (!item) {
- return '';
- }
- return `${item.itemCode ?? ''} - ${item.itemName ?? ''}`;
-});
-
-const showClear = computed(
- () =>
- props.allowClear &&
- !props.disabled &&
- hovering.value &&
- props.modelValue !== null,
-);
-
-/** 鏍规嵁缂栧彿鍗曟潯鏌ヨ琛屼俊鎭紙鐢ㄤ簬缂栬緫鍥炴樉锛� */
-async function resolveItemById(id: number | undefined) {
- if (!id) {
- selectedItem.value = undefined;
- return;
- }
- if (selectedItem.value?.id === id) {
- return;
- }
- selectedItem.value = await getSalesNoticeLine(id);
-}
-
-watch(() => props.modelValue, resolveItemById, { immediate: true });
-
-/** noticeId 鍙樺寲鏃舵竻绌洪�変腑锛堝叧鑱旂殑琛屽凡澶辨晥锛� */
-watch(
- () => props.noticeId,
- () => {
- selectedItem.value = undefined;
- emit('update:modelValue', undefined);
- emit('change', undefined);
- },
-);
-
-/** 娓呯┖宸查�夎 */
-function clearSelected() {
- selectedItem.value = undefined;
- emit('update:modelValue', undefined);
- emit('change', undefined);
-}
-
-/** 鎵撳紑琛岄�夋嫨寮圭獥 */
-function handleClick(event: MouseEvent) {
- if (props.disabled || !props.noticeId) {
- 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]
- ) as number[];
- dialogRef.value?.open(props.noticeId, selectedIds);
-}
-
-/** 寮圭獥閫変腑鍥炶皟 */
-function handleSelected(rows: MesWmSalesNoticeLineApi.SalesNoticeLine[]) {
- const item = rows[0];
- if (!item) {
- return;
- }
- selectedItem.value = item;
- emit('update:modelValue', item.id);
- emit('change', item);
-}
-</script>
-
-<template>
- <div
- v-bind="attrs"
- class="w-full"
- :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.itemCode || '-' }}</div>
- <div>鐗╂枡鍚嶇О锛歿{ selectedItem.itemName || '-' }}</div>
- <div>瑙勬牸鍨嬪彿锛歿{ selectedItem.specification || '-' }}</div>
- <div>鍙戣揣鏁伴噺锛歿{ selectedItem.quantity ?? '-' }}</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>
- <WmSalesNoticeLineSelectDialog ref="dialogRef" @selected="handleSelected" />
-</template>
diff --git a/src/views/salesnotice/components/select-dialog.vue b/src/views/salesnotice/components/select-dialog.vue
deleted file mode 100644
index 8c5c8ef..0000000
--- a/src/views/salesnotice/components/select-dialog.vue
+++ /dev/null
@@ -1,320 +0,0 @@
-<script lang="ts" setup>
-import type { VbenFormSchema } from '#/adapter/form';
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmSalesNoticeApi } from '#/api/mes/wm/salesnotice';
-
-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[]];
-}>();
-
-const open = ref(false); // 寮圭獥鏄惁鎵撳紑
-const multiple = ref(false); // 鏄惁澶氶��
-const fixedStatus = ref<number>(); // 鍥哄畾鐘舵�佺瓫閫�
-const selectedRows = ref<MesWmSalesNoticeApi.SalesNotice[]>([]); // 宸查�夐�氱煡鍗曞垪琛�
-const preSelectedIds = ref<number[]>([]); // 棰勯�夐�氱煡鍗曠紪鍙峰垪琛�
-
-/** 鎼滅储琛ㄥ崟锛氭湭鍥哄畾鐘舵�佹椂灞曠ず鐘舵�佷笅鎷夛紝鍥哄畾鐘舵�佹椂闅愯棌 */
-function useSearchSchema(hasFixedStatus: boolean): VbenFormSchema[] {
- return [
- {
- fieldName: 'code',
- label: '閫氱煡鍗曠紪鍙�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ラ�氱煡鍗曠紪鍙�',
- },
- },
- {
- fieldName: 'name',
- label: '閫氱煡鍗曞悕绉�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ラ�氱煡鍗曞悕绉�',
- },
- },
- {
- fieldName: 'salesOrderCode',
- label: '閿�鍞鍗曠紪鍙�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- 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,
- ]),
- ];
-}
-
-/** 琛ㄦ牸瀛楁 */
-function useGridColumns(
- multipleSelect = false,
-): VxeTableGridOptions<MesWmSalesNoticeApi.SalesNotice>['columns'] {
- return [
- {
- type: multipleSelect ? 'checkbox' : 'radio',
- width: 50,
- },
- {
- field: 'code',
- title: '閫氱煡鍗曠紪鍙�',
- minWidth: 160,
- },
- {
- field: 'name',
- title: '閫氱煡鍗曞悕绉�',
- minWidth: 150,
- },
- {
- field: 'salesOrderCode',
- title: '閿�鍞鍗曠紪鍙�',
- minWidth: 140,
- },
- {
- field: 'clientName',
- title: '瀹㈡埛鍚嶇О',
- minWidth: 120,
- },
- {
- field: 'salesDate',
- title: '鍙戣揣鏃ユ湡',
- width: 120,
- formatter: 'formatDate',
- },
- {
- field: 'status',
- title: '鍗曟嵁鐘舵��',
- width: 100,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_SALES_NOTICE_STATUS },
- },
- },
- ];
-}
-
-/** 鑾峰彇澶氶�夎褰曪紝鍖呭惈 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()];
-}
-
-/** 澶勭悊澶氶�夊嬀閫夊彉鍖� */
-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,
-}: {
- row: MesWmSalesNoticeApi.SalesNotice;
-}) {
- if (multiple.value) {
- await toggleMultipleRow(row);
- return;
- }
- selectedRows.value = [row];
- await gridApi.grid.setRadioRow(row);
- handleConfirm();
-}
-
-/** 鍥炴樉棰勯�夐�氱煡鍗� */
-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 === 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();
- }
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- formOptions: {
- schema: useSearchSchema(false),
- },
- gridOptions: {
- columns: useGridColumns(false),
- height: 520,
- keepSource: true,
- checkboxConfig: {
- highlight: true,
- range: true,
- reserve: true,
- },
- radioConfig: {
- highlight: true,
- trigger: 'row',
- },
- proxyConfig: {
- ajax: {
- query: async ({ page }, formValues) => {
- return await getSalesNoticePage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- ...formValues,
- // 鍥哄畾鐘舵�佷紭鍏堬紝鏈浐瀹氭椂鐢ㄦ悳绱㈣〃鍗曢噷鐨勭姸鎬�
- status: fixedStatus.value ?? formValues.status,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- search: true,
- },
- } as VxeTableGridOptions<MesWmSalesNoticeApi.SalesNotice>,
- gridEvents: {
- cellDblclick: handleCellDblclick,
- checkboxAll: handleCheckboxSelectChange,
- checkboxChange: handleCheckboxSelectChange,
- radioChange: ({ row }: { row: MesWmSalesNoticeApi.SalesNotice }) => {
- handleRadioChange(row);
- },
- },
-});
-
-/** 閲嶇疆鏌ヨ鍜岄�夋嫨鐘舵�� */
-async function resetQueryState() {
- selectedRows.value = [];
- await gridApi.grid.clearCheckboxRow();
- await gridApi.grid.clearCheckboxReserve();
- await gridApi.grid.clearRadioRow();
- await gridApi.formApi.resetForm();
-}
-
-/** 鎵撳紑閫氱煡鍗曢�夋嫨寮圭獥 */
-async function openModal(
- selectedIds?: number[],
- options?: { multiple?: boolean; status?: number },
-) {
- open.value = true;
- multiple.value = options?.multiple ?? false;
- fixedStatus.value = options?.status;
- preSelectedIds.value = selectedIds || [];
- // 鍥哄畾鐘舵�佹椂闅愯棌鐘舵�佹悳绱㈤」锛屾湭鍥哄畾鏃跺睍绀�
- gridApi.formApi.setState({
- schema: useSearchSchema(fixedStatus.value !== undefined),
- });
- await nextTick();
- gridApi.setGridOptions({
- columns: useGridColumns(multiple.value),
- });
- await resetQueryState();
- await gridApi.query();
- await nextTick();
- await applyPreSelection();
-}
-
-/** 鍏抽棴閫氱煡鍗曢�夋嫨寮圭獥 */
-async function closeModal() {
- open.value = false;
- await resetQueryState();
-}
-
-/** 纭閫夋嫨閫氱煡鍗� */
-function handleConfirm() {
- if (selectedRows.value.length === 0) {
- message.warning(multiple.value ? '璇疯嚦灏戦�夋嫨涓�鏉℃暟鎹�' : '璇烽�夋嫨涓�鏉℃暟鎹�');
- return;
- }
- emit(
- 'selected',
- multiple.value ? selectedRows.value : [selectedRows.value[0]!],
- );
- open.value = false;
-}
-
-defineExpose({ open: openModal });
-</script>
-
-<template>
- <Modal
- v-model:open="open"
- title="鍙戣揣閫氱煡鍗曢�夋嫨"
- width="70%"
- :destroy-on-close="true"
- @cancel="closeModal"
- @ok="handleConfirm"
- >
- <Grid table-title="鍙戣揣閫氱煡鍗曞垪琛�" />
- </Modal>
-</template>
diff --git a/src/views/salesnotice/components/select.vue b/src/views/salesnotice/components/select.vue
deleted file mode 100644
index ee19d2c..0000000
--- a/src/views/salesnotice/components/select.vue
+++ /dev/null
@@ -1,141 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmSalesNoticeApi } from '#/api/mes/wm/salesnotice';
-
-import { computed, ref, useAttrs, watch } from 'vue';
-
-import { IconifyIcon } from '@vben/icons';
-
-import { Input, Tooltip } from 'ant-design-vue';
-
-import { getSalesNotice } from '#/api/mes/wm/salesnotice';
-
-import WmSalesNoticeSelectDialog from './select-dialog.vue';
-
-defineOptions({ name: 'WmSalesNoticeSelect', inheritAttrs: false });
-
-const props = withDefaults(
- defineProps<{
- allowClear?: boolean;
- disabled?: boolean;
- modelValue?: number;
- placeholder?: string;
- status?: number; // 鍥哄畾鐘舵�佺瓫閫�
- }>(),
- {
- allowClear: true,
- disabled: false,
- modelValue: undefined,
- placeholder: '璇烽�夋嫨鍙戣揣閫氱煡鍗�',
- status: undefined,
- },
-);
-
-const emit = defineEmits<{
- change: [item: MesWmSalesNoticeApi.SalesNotice | undefined];
- 'update:modelValue': [value: number | undefined];
-}>();
-
-const attrs = useAttrs();
-const dialogRef = ref<InstanceType<typeof WmSalesNoticeSelectDialog>>();
-const hovering = ref(false);
-const selectedItem = ref<MesWmSalesNoticeApi.SalesNotice>();
-
-const displayLabel = computed(() => selectedItem.value?.name ?? '');
-
-const showClear = computed(
- () =>
- props.allowClear &&
- !props.disabled &&
- hovering.value &&
- props.modelValue !== undefined &&
- props.modelValue !== null,
-);
-
-/** 鏍规嵁缂栧彿鍗曟潯鏌ヨ閫氱煡鍗曚俊鎭紙鐢ㄤ簬缂栬緫鍥炴樉锛� */
-async function resolveItemById(id: number | undefined) {
- if (!id) {
- selectedItem.value = undefined;
- return;
- }
- if (selectedItem.value?.id === id) {
- return;
- }
- selectedItem.value = await getSalesNotice(id);
-}
-
-watch(() => props.modelValue, resolveItemById, { 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]
- ) as number[];
- dialogRef.value?.open(selectedIds, {
- multiple: false,
- status: props.status,
- });
-}
-
-/** 寮圭獥閫変腑鍥炶皟 */
-function handleSelected(rows: MesWmSalesNoticeApi.SalesNotice[]) {
- const item = rows[0];
- if (!item) {
- return;
- }
- selectedItem.value = item;
- emit('update:modelValue', item.id);
- emit('change', item);
-}
-</script>
-
-<template>
- <div
- v-bind="attrs"
- class="w-full"
- :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>瀹㈡埛锛歿{ selectedItem.clientName || '-' }}</div>
- <div>閿�鍞鍗曪細{{ selectedItem.salesOrderCode || '-' }}</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>
- <WmSalesNoticeSelectDialog ref="dialogRef" @selected="handleSelected" />
-</template>
diff --git a/src/views/salesnotice/data.ts b/src/views/salesnotice/data.ts
deleted file mode 100644
index f9a1931..0000000
--- a/src/views/salesnotice/data.ts
+++ /dev/null
@@ -1,362 +0,0 @@
-import type { VbenFormApi, VbenFormSchema } from '#/adapter/form';
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmSalesNoticeApi } from '#/api/mes/wm/salesnotice';
-import type { MesWmSalesNoticeLineApi } from '#/api/mes/wm/salesnotice/line';
-
-import { h, markRaw } from 'vue';
-
-import { DICT_TYPE, MesAutoCodeRuleCode } from '@vben/constants';
-
-import { Button } from 'ant-design-vue';
-
-import { z } from '#/adapter/form';
-import { generateAutoCode } from '#/api/mes/md/autocode/record';
-import { MdClientSelect } from '#/views/mes/md/client/components';
-import { MdItemSelect } from '#/views/mes/md/item/components';
-
-/** 琛ㄥ崟绫诲瀷 */
-export type FormType = 'create' | 'detail' | 'finish' | 'update';
-
-/** 琛ㄥ崟澶撮儴鏄惁鍙锛堣鎯呫�佹墽琛屽嚭搴撴�侊級 */
-function isHeaderReadonly(formType: FormType): boolean {
- return formType === 'detail' || formType === 'finish';
-}
-
-/** 鏂板/淇敼鐨勮〃鍗� */
-export function useFormSchema(
- formType: FormType,
- formApi?: VbenFormApi,
-): VbenFormSchema[] {
- return [
- {
- fieldName: 'id',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'status',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'code',
- label: '閫氱煡鍗曠紪鍙�',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ラ�氱煡鍗曠紪鍙�',
- },
- rules: 'required',
- suffix: isHeaderReadonly(formType)
- ? undefined
- : () =>
- h(
- Button,
- {
- type: 'default',
- onClick: async () => {
- const code = await generateAutoCode(
- MesAutoCodeRuleCode.WM_SALES_NOTICE_CODE,
- );
- await formApi?.setFieldValue('code', code);
- },
- },
- { default: () => '鐢熸垚' },
- ),
- },
- {
- fieldName: 'name',
- label: '閫氱煡鍗曞悕绉�',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ラ�氱煡鍗曞悕绉�',
- },
- rules: 'required',
- },
- {
- fieldName: 'salesOrderCode',
- label: '閿�鍞鍗曠紪鍙�',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ラ攢鍞鍗曠紪鍙�',
- },
- },
- {
- fieldName: 'clientId',
- label: '瀹㈡埛',
- component: markRaw(MdClientSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨瀹㈡埛',
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'salesDate',
- label: '鍙戣揣鏃ユ湡',
- component: 'DatePicker',
- componentProps: {
- class: '!w-full',
- format: 'YYYY-MM-DD',
- placeholder: '璇烽�夋嫨鍙戣揣鏃ユ湡',
- valueFormat: 'x',
- },
- rules: 'required',
- },
- {
- fieldName: 'recipientName',
- label: '鏀惰揣浜�',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ユ敹璐т汉',
- },
- },
- {
- fieldName: 'recipientTelephone',
- label: '鑱旂郴鏂瑰紡',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ヨ仈绯绘柟寮�',
- },
- },
- {
- fieldName: 'recipientAddress',
- label: '鏀惰揣鍦板潃',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ユ敹璐у湴鍧�',
- },
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勬悳绱㈣〃鍗� */
-export function useGridFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'code',
- label: '閫氱煡鍗曠紪鍙�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ラ�氱煡鍗曠紪鍙�',
- },
- },
- {
- fieldName: 'name',
- label: '閫氱煡鍗曞悕绉�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ラ�氱煡鍗曞悕绉�',
- },
- },
- {
- fieldName: 'salesOrderCode',
- label: '閿�鍞鍗曠紪鍙�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ラ攢鍞鍗曠紪鍙�',
- },
- },
- {
- fieldName: 'clientId',
- label: '瀹㈡埛',
- component: markRaw(MdClientSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨瀹㈡埛',
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勫瓧娈� */
-export function useGridColumns(): VxeTableGridOptions<MesWmSalesNoticeApi.SalesNotice>['columns'] {
- return [
- {
- field: 'code',
- title: '閫氱煡鍗曠紪鍙�',
- minWidth: 160,
- slots: { default: 'code' },
- },
- {
- field: 'name',
- title: '閫氱煡鍗曞悕绉�',
- minWidth: 150,
- },
- {
- field: 'salesOrderCode',
- title: '閿�鍞鍗曠紪鍙�',
- minWidth: 140,
- },
- {
- field: 'clientName',
- title: '瀹㈡埛鍚嶇О',
- minWidth: 120,
- },
- {
- field: 'salesDate',
- title: '鍙戣揣鏃ユ湡',
- width: 180,
- formatter: 'formatDate',
- },
- {
- field: 'recipientName',
- title: '鏀惰揣浜�',
- minWidth: 100,
- },
- {
- field: 'recipientTelephone',
- title: '鑱旂郴鏂瑰紡',
- minWidth: 120,
- },
- {
- field: 'recipientAddress',
- title: '鏀惰揣鍦板潃',
- minWidth: 200,
- },
- {
- field: 'status',
- title: '鍗曟嵁鐘舵��',
- minWidth: 100,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_SALES_NOTICE_STATUS },
- },
- },
- {
- title: '鎿嶄綔',
- width: 200,
- fixed: 'right',
- slots: { default: 'actions' },
- },
- ];
-}
-
-/** 閫氱煡鍗曡瀛愯〃鐨勫瓧娈� */
-export function useLineGridColumns(
- editable: boolean,
-): VxeTableGridOptions<MesWmSalesNoticeLineApi.SalesNoticeLine>['columns'] {
- return [
- {
- field: 'itemCode',
- title: '鐗╂枡缂栫爜',
- minWidth: 120,
- },
- {
- field: 'itemName',
- title: '鐗╂枡鍚嶇О',
- minWidth: 140,
- },
- {
- field: 'specification',
- title: '瑙勬牸鍨嬪彿',
- minWidth: 120,
- },
- {
- field: 'unitMeasureName',
- title: '鍗曚綅',
- width: 80,
- },
- {
- field: 'quantity',
- title: '鍙戣揣鏁伴噺',
- width: 100,
- },
- {
- field: 'batchCode',
- title: '鎵规鍙�',
- minWidth: 120,
- },
- {
- field: 'oqcCheckFlag',
- title: '鏄惁妫�楠�',
- width: 90,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.INFRA_BOOLEAN_STRING },
- },
- },
- {
- field: 'remark',
- title: '澶囨敞',
- minWidth: 120,
- },
- ...(editable
- ? [
- {
- title: '鎿嶄綔',
- width: 120,
- fixed: 'right',
- slots: { default: 'actions' },
- } as const,
- ]
- : []),
- ];
-}
-
-/** 閫氱煡鍗曡鏂板/淇敼鐨勮〃鍗� */
-export function useLineFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'itemId',
- label: '鐗╂枡',
- component: markRaw(MdItemSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨鐗╂枡',
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'quantity',
- label: '鍙戣揣鏁伴噺',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0.01,
- placeholder: '璇疯緭鍏ュ彂璐ф暟閲�',
- precision: 2,
- },
- rules: 'required',
- },
- {
- fieldName: 'batchCode',
- label: '鎵规鍙�',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ユ壒娆″彿',
- },
- },
- {
- fieldName: 'oqcCheckFlag',
- label: '鏄惁妫�楠�',
- component: 'Switch',
- rules: z.boolean().default(true),
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
diff --git a/src/views/salesnotice/index.vue b/src/views/salesnotice/index.vue
deleted file mode 100644
index cd323e8..0000000
--- a/src/views/salesnotice/index.vue
+++ /dev/null
@@ -1,168 +0,0 @@
-<script lang="ts" setup>
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmSalesNoticeApi } from '#/api/mes/wm/salesnotice';
-
-import { Page, useVbenModal } from '@vben/common-ui';
-import { MesWmSalesNoticeStatusEnum } from '@vben/constants';
-import { downloadFileFromBlobPart } from '@vben/utils';
-
-import { Button, message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import {
- deleteSalesNotice,
- exportSalesNotice,
- getSalesNoticePage,
-} from '#/api/mes/wm/salesnotice';
-import { $t } from '#/locales';
-
-import { useGridColumns, useGridFormSchema } from './data';
-import Form from './modules/form.vue';
-
-const [FormModal, formModalApi] = useVbenModal({
- connectedComponent: Form,
- destroyOnClose: true,
-});
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- gridApi.query();
-}
-
-/** 鍒涘缓鍙戣揣閫氱煡鍗� */
-function handleCreate() {
- formModalApi.setData({ formType: 'create' }).open();
-}
-
-/** 鏌ョ湅鍙戣揣閫氱煡鍗� */
-function handleDetail(row: MesWmSalesNoticeApi.SalesNotice) {
- formModalApi.setData({ formType: 'detail', id: row.id }).open();
-}
-
-/** 缂栬緫鍙戣揣閫氱煡鍗� */
-function handleEdit(row: MesWmSalesNoticeApi.SalesNotice) {
- formModalApi.setData({ formType: 'update', id: row.id }).open();
-}
-
-/** 鎵ц鍑哄簱 */
-function handleFinish(row: MesWmSalesNoticeApi.SalesNotice) {
- formModalApi.setData({ formType: 'finish', id: row.id }).open();
-}
-
-/** 鍒犻櫎鍙戣揣閫氱煡鍗� */
-async function handleDelete(row: MesWmSalesNoticeApi.SalesNotice) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.code]),
- duration: 0,
- });
- try {
- await deleteSalesNotice(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.code]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-/** 瀵煎嚭琛ㄦ牸 */
-async function handleExport() {
- const data = await exportSalesNotice(await gridApi.formApi.getValues());
- downloadFileFromBlobPart({ fileName: '鍙戣揣閫氱煡鍗�.xls', source: data });
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- formOptions: {
- schema: useGridFormSchema(),
- },
- gridOptions: {
- columns: useGridColumns(),
- height: 'auto',
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }, formValues) => {
- return await getSalesNoticePage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- ...formValues,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- search: true,
- },
- } as VxeTableGridOptions<MesWmSalesNoticeApi.SalesNotice>,
-});
-</script>
-
-<template>
- <Page auto-content-height><FormModal @success="handleRefresh" />
-
- <Grid table-title="鍙戣揣閫氱煡鍗曞垪琛�">
- <template #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: $t('ui.actionTitle.create', ['鍙戣揣閫氱煡鍗�']),
- type: 'primary',
- icon: ACTION_ICON.ADD,
- auth: ['mes:wm-sales-notice:create'],
- onClick: handleCreate,
- },
- {
- label: $t('ui.actionTitle.export'),
- type: 'primary',
- icon: ACTION_ICON.DOWNLOAD,
- auth: ['mes:wm-sales-notice:export'],
- onClick: handleExport,
- },
- ]"
- />
- </template>
- <template #code="{ row }">
- <Button type="link" @click="handleDetail(row)">
- {{ row.code }}
- </Button>
- </template>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- auth: ['mes:wm-sales-notice:update'],
- ifShow: row.status === MesWmSalesNoticeStatusEnum.PREPARE,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- auth: ['mes:wm-sales-notice:delete'],
- ifShow: row.status === MesWmSalesNoticeStatusEnum.PREPARE,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.code]),
- confirm: handleDelete.bind(null, row),
- },
- },
- {
- label: '鎵ц鍑哄簱',
- type: 'link',
- auth: ['mes:wm-sales-notice:update'],
- ifShow: row.status === MesWmSalesNoticeStatusEnum.APPROVED,
- onClick: handleFinish.bind(null, row),
- },
- ]"
- />
- </template>
- </Grid>
- </Page>
-</template>
diff --git a/src/views/salesnotice/modules/form.vue b/src/views/salesnotice/modules/form.vue
deleted file mode 100644
index a351b94..0000000
--- a/src/views/salesnotice/modules/form.vue
+++ /dev/null
@@ -1,182 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { MesWmSalesNoticeApi } from '#/api/mes/wm/salesnotice';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-import { MesWmSalesNoticeStatusEnum } from '@vben/constants';
-
-import { Button, Divider, message, Popconfirm } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createSalesNotice,
- getSalesNotice,
- submitSalesNotice,
- updateSalesNotice,
-} from '#/api/mes/wm/salesnotice';
-import { $t } from '#/locales';
-
-import { useFormSchema } from '../data';
-import LineList from './line-list.vue';
-
-const emit = defineEmits(['success']);
-const formType = ref<FormType>('create');
-const formData = ref<MesWmSalesNoticeApi.SalesNotice>();
-const originalSnapshot = ref(''); // 琛ㄥ崟鍘熷鏁版嵁蹇収锛岀敤浜庢彁浜ゆ椂璺宠繃鏈彉鏇寸殑淇濆瓨璇锋眰
-const isEditable = computed(() =>
- // 鏄惁涓虹紪杈戞ā寮忥紙鍙繚瀛橈級
- ['create', 'update'].includes(formType.value),
-);
-const isFinish = computed(() => formType.value === 'finish'); // 鏄惁涓烘墽琛屽嚭搴撴ā寮�
-const canSubmit = computed(
- () =>
- // 鏄惁鍙彁浜�
- formType.value === 'update' &&
- formData.value?.status === MesWmSalesNoticeStatusEnum.PREPARE,
-);
-const getTitle = computed(() => {
- if (formType.value === 'detail') {
- return $t('ui.actionTitle.view', ['鍙戣揣閫氱煡鍗�']);
- }
- if (formType.value === 'finish') {
- return '鎵ц鍑哄簱';
- }
- return formType.value === 'update'
- ? $t('ui.actionTitle.edit', ['鍙戣揣閫氱煡鍗�'])
- : $t('ui.actionTitle.create', ['鍙戣揣閫氱煡鍗�']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 110,
- },
- layout: 'horizontal',
- schema: [],
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-/** 鎻愪氦閫氱煡鍗曪細琛ㄥ崟鏈変慨鏀规椂鍏堜繚瀛橈紝鍐嶈皟鐢ㄦ彁浜ゆ帴鍙� */
-async function handleSubmit() {
- const { valid } = await formApi.validate();
- if (!valid || !formData.value?.id) {
- return;
- }
- modalApi.lock();
- try {
- const current = JSON.stringify(await formApi.getValues());
- if (current !== originalSnapshot.value) {
- const data =
- (await formApi.getValues()) as MesWmSalesNoticeApi.SalesNotice;
- await updateSalesNotice({ ...formData.value, ...data });
- originalSnapshot.value = current;
- }
- await submitSalesNotice(formData.value.id);
- message.success('鎻愪氦鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-/** 鎵ц鍑哄簱锛堝悗绔殏鏈疄鐜帮紝鎻愮ず鐢ㄦ埛锛� */
-function handleFinish() {
- message.info('鎵ц鍑哄簱鍔熻兘鏆傛椂涓嶆敮鎸侊紝鏁鏈熷緟锛�');
-}
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- if (!isEditable.value) {
- await modalApi.close();
- return;
- }
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data = (await formApi.getValues()) as MesWmSalesNoticeApi.SalesNotice;
- try {
- if (formData.value?.id) {
- await updateSalesNotice({ ...formData.value, ...data });
- formData.value = { ...formData.value, ...data };
- } else {
- const id = await createSalesNotice(data);
- formData.value = {
- ...data,
- id,
- status: MesWmSalesNoticeStatusEnum.PREPARE,
- };
- await formApi.setFieldValue('id', id);
- await formApi.setFieldValue('status', formData.value.status);
- formType.value = 'update';
- }
- originalSnapshot.value = JSON.stringify(await formApi.getValues());
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- originalSnapshot.value = '';
- return;
- }
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{ formType: FormType; id?: number }>();
- formType.value = data.formType;
- formApi.setState({ schema: useFormSchema(formType.value, formApi) });
- formApi.setDisabled(!isEditable.value);
- modalApi.setState({ showConfirmButton: isEditable.value });
- if (data?.id) {
- modalApi.lock();
- try {
- formData.value = await getSalesNotice(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- }
- originalSnapshot.value = JSON.stringify(await formApi.getValues());
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- <!-- 闈炴柊寤烘ā寮忓睍绀虹墿鏂欎俊鎭� -->
- <template v-if="formData?.id">
- <Divider>鐗╂枡淇℃伅</Divider>
- <div class="mx-4">
- <LineList :form-type="formType" :notice-id="formData.id" />
- </div>
- </template>
- <template #prepend-footer>
- <div class="flex flex-auto items-center gap-2">
- <Popconfirm
- v-if="canSubmit"
- title="纭鎻愪氦璇ュ彂璐ч�氱煡鍗曪紵銆愭彁浜ゅ悗灏嗕笉鑳戒慨鏀广��"
- @confirm="handleSubmit"
- >
- <Button type="primary">鎻愪氦</Button>
- </Popconfirm>
- <Button v-if="isFinish" type="primary" @click="handleFinish">
- 鎵ц鍑哄簱
- </Button>
- </div>
- </template>
- </Modal>
-</template>
diff --git a/src/views/salesnotice/modules/line-form.vue b/src/views/salesnotice/modules/line-form.vue
deleted file mode 100644
index f33e49a..0000000
--- a/src/views/salesnotice/modules/line-form.vue
+++ /dev/null
@@ -1,94 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmSalesNoticeLineApi } from '#/api/mes/wm/salesnotice/line';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createSalesNoticeLine,
- getSalesNoticeLine,
- updateSalesNoticeLine,
-} from '#/api/mes/wm/salesnotice/line';
-import { $t } from '#/locales';
-
-import { useLineFormSchema } from '../data';
-
-const emit = defineEmits(['success']);
-const formData = ref<MesWmSalesNoticeLineApi.SalesNoticeLine>();
-const noticeId = ref<number>(); // 鎵�灞為�氱煡鍗曠紪鍙�
-
-const getTitle = computed(() => {
- return formData.value?.id
- ? $t('ui.actionTitle.edit', ['鍙戣揣閫氱煡鍗曡'])
- : $t('ui.actionTitle.create', ['鍙戣揣閫氱煡鍗曡']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 90,
- },
- layout: 'horizontal',
- schema: useLineFormSchema(),
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data =
- (await formApi.getValues()) as MesWmSalesNoticeLineApi.SalesNoticeLine;
- data.noticeId = noticeId.value;
- try {
- await (formData.value?.id
- ? updateSalesNoticeLine({ ...data, id: formData.value.id })
- : createSalesNoticeLine(data));
- // 鍏抽棴骞舵彁绀�
- await modalApi.close();
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- return;
- }
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{ id?: number; noticeId: number }>();
- noticeId.value = data.noticeId;
- if (!data.id) {
- return;
- }
- modalApi.lock();
- try {
- formData.value = await getSalesNoticeLine(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- </Modal>
-</template>
diff --git a/src/views/salesnotice/modules/line-list.vue b/src/views/salesnotice/modules/line-list.vue
deleted file mode 100644
index d323aa0..0000000
--- a/src/views/salesnotice/modules/line-list.vue
+++ /dev/null
@@ -1,140 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmSalesNoticeLineApi } from '#/api/mes/wm/salesnotice/line';
-
-import { computed } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import {
- deleteSalesNoticeLine,
- getSalesNoticeLinePage,
-} from '#/api/mes/wm/salesnotice/line';
-import { $t } from '#/locales';
-
-import { useLineGridColumns } from '../data';
-import LineForm from './line-form.vue';
-
-const props = defineProps<{
- formType: FormType;
- noticeId: number;
-}>();
-
-const isEditable = computed(() =>
- // 鏄惁鍙紪杈戞槑缁嗚
- ['create', 'update'].includes(props.formType),
-);
-
-const [LineFormModal, lineFormModalApi] = useVbenModal({
- connectedComponent: LineForm,
- destroyOnClose: true,
-});
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- gridApi.query();
-}
-
-/** 娣诲姞鐗╂枡 */
-function handleCreate() {
- lineFormModalApi.setData({ noticeId: props.noticeId }).open();
-}
-
-/** 缂栬緫鐗╂枡 */
-function handleEdit(row: MesWmSalesNoticeLineApi.SalesNoticeLine) {
- lineFormModalApi.setData({ id: row.id, noticeId: props.noticeId }).open();
-}
-
-/** 鍒犻櫎鐗╂枡 */
-async function handleDelete(row: MesWmSalesNoticeLineApi.SalesNoticeLine) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.itemName]),
- duration: 0,
- });
- try {
- await deleteSalesNoticeLine(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.itemName]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- gridOptions: {
- columns: useLineGridColumns(isEditable.value),
- height: 400,
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }) => {
- if (!props.noticeId) {
- return { list: [], total: 0 };
- }
- return await getSalesNoticeLinePage({
- noticeId: props.noticeId,
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- },
- } as VxeTableGridOptions<MesWmSalesNoticeLineApi.SalesNoticeLine>,
-});
-</script>
-
-<template>
- <div>
- <LineFormModal @success="handleRefresh" />
- <Grid table-title="鐗╂枡淇℃伅">
- <template v-if="isEditable" #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: '娣诲姞鐗╂枡',
- type: 'primary',
- icon: ACTION_ICON.ADD,
- onClick: handleCreate,
- },
- ]"
- />
- </template>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- ifShow: isEditable,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- ifShow: isEditable,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.itemName]),
- confirm: handleDelete.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </div>
-</template>
diff --git a/src/views/sn/data.ts b/src/views/sn/data.ts
deleted file mode 100644
index 2023366..0000000
--- a/src/views/sn/data.ts
+++ /dev/null
@@ -1,183 +0,0 @@
-import type { VbenFormSchema } from '#/adapter/form';
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmSnApi } from '#/api/mes/wm/sn';
-
-import { markRaw } from 'vue';
-
-import { getRangePickerDefaultProps } from '#/utils';
-import { MdItemSelect } from '#/views/mes/md/item/components';
-
-/** 鐢熸垚 SN 鐮佺殑琛ㄥ崟 */
-export function useFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'itemId',
- label: '鐗╂枡',
- component: markRaw(MdItemSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨鐗╂枡',
- },
- rules: 'required',
- },
- {
- fieldName: 'batchCode',
- label: '鎵规鍙�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- maxlength: 100,
- placeholder: '璇疯緭鍏ユ壒娆″彿',
- },
- },
- {
- fieldName: 'count',
- label: '鐢熸垚鏁伴噺',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- max: 1000,
- min: 1,
- placeholder: '璇疯緭鍏ョ敓鎴愭暟閲�',
- },
- rules: 'required',
- },
- ];
-}
-
-/** 鍒楄〃鐨勬悳绱㈣〃鍗� */
-export function useGridFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'code',
- label: 'SN 鐮�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏� SN 鐮�',
- },
- },
- {
- fieldName: 'itemId',
- label: '鐗╂枡',
- component: markRaw(MdItemSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨鐗╂枡',
- },
- },
- {
- fieldName: 'batchCode',
- label: '鎵规鍙�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ユ壒娆″彿',
- },
- },
- {
- fieldName: 'createTime',
- label: '鍒涘缓鏃堕棿',
- component: 'RangePicker',
- componentProps: {
- ...getRangePickerDefaultProps(),
- allowClear: true,
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勫瓧娈� */
-export function useGridColumns(): VxeTableGridOptions<MesWmSnApi.SnGroup>['columns'] {
- return [
- {
- field: 'itemCode',
- title: '鐗╂枡缂栫爜',
- minWidth: 120,
- },
- {
- field: 'itemName',
- title: '鐗╂枡鍚嶇О',
- minWidth: 150,
- },
- {
- field: 'specification',
- title: '瑙勬牸鍨嬪彿',
- minWidth: 120,
- },
- {
- field: 'unitName',
- title: '鍗曚綅',
- width: 80,
- },
- {
- field: 'batchCode',
- title: '鎵规鍙�',
- minWidth: 120,
- },
- {
- field: 'count',
- title: 'SN 鐮佹暟閲�',
- width: 100,
- slots: { default: 'count' },
- },
- {
- field: 'createTime',
- title: '鐢熸垚鏃堕棿',
- width: 180,
- formatter: 'formatDateTime',
- },
- {
- title: '鎿嶄綔',
- width: 240,
- fixed: 'right',
- slots: { default: 'actions' },
- },
- ];
-}
-
-/** SN 鐮佹槑缁嗗脊绐楃殑瀛楁 */
-export function useDetailGridColumns(): VxeTableGridOptions<MesWmSnApi.Sn>['columns'] {
- return [
- {
- field: 'code',
- title: 'SN 鐮�',
- minWidth: 180,
- },
- {
- field: 'itemCode',
- title: '鐗╂枡缂栫爜',
- minWidth: 120,
- },
- {
- field: 'itemName',
- title: '鐗╂枡鍚嶇О',
- minWidth: 150,
- },
- {
- field: 'specification',
- title: '瑙勬牸鍨嬪彿',
- minWidth: 120,
- },
- {
- field: 'unitName',
- title: '鍗曚綅',
- width: 80,
- },
- {
- field: 'batchCode',
- title: '鎵规鍙�',
- minWidth: 120,
- },
- {
- field: 'createTime',
- title: '鐢熸垚鏃堕棿',
- width: 180,
- formatter: 'formatDateTime',
- },
- {
- title: '鎿嶄綔',
- width: 100,
- fixed: 'right',
- slots: { default: 'actions' },
- },
- ];
-}
diff --git a/src/views/sn/index.vue b/src/views/sn/index.vue
deleted file mode 100644
index c881303..0000000
--- a/src/views/sn/index.vue
+++ /dev/null
@@ -1,177 +0,0 @@
-<script lang="ts" setup>
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmSnApi } from '#/api/mes/wm/sn';
-
-import { Page, useVbenModal } from '@vben/common-ui';
-import { downloadFileFromBlobPart } from '@vben/utils';
-
-import { message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import {
- deleteSnBatch,
- exportSnDetailExcel,
- exportSnGroupExcel,
- getSnGroupPage,
-} from '#/api/mes/wm/sn';
-import { $t } from '#/locales';
-
-import { useGridColumns, useGridFormSchema } from './data';
-import Detail from './modules/detail.vue';
-import Form from './modules/form.vue';
-
-const [FormModal, formModalApi] = useVbenModal({
- connectedComponent: Form,
- destroyOnClose: true,
-});
-
-const [DetailModal, detailModalApi] = useVbenModal({
- connectedComponent: Detail,
- destroyOnClose: true,
-});
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- gridApi.query();
-}
-
-/** 鐢熸垚 SN 鐮� */
-function handleCreate() {
- formModalApi.setData(null).open();
-}
-
-/** 瀵煎嚭鍒嗙粍琛ㄦ牸 */
-async function handleExport() {
- const data = await exportSnGroupExcel(await gridApi.formApi.getValues());
- downloadFileFromBlobPart({ fileName: 'SN鐮佸垎缁�.xls', source: data });
-}
-
-/** 瀵煎嚭鎵规鏄庣粏 */
-async function handleExportDetail(row: MesWmSnApi.SnGroup) {
- const data = await exportSnDetailExcel(row.uuid!);
- downloadFileFromBlobPart({ fileName: 'SN鐮佹槑缁�.xls', source: data });
-}
-
-/** 鏌ョ湅 SN 鐮佹槑缁� */
-function handleDetail(row: MesWmSnApi.SnGroup) {
- detailModalApi.setData(row).open();
-}
-
-/** 鍒犻櫎 SN 鐮佹壒娆� */
-async function handleDelete(row: MesWmSnApi.SnGroup) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.batchCode || row.itemName]),
- duration: 0,
- });
- try {
- await deleteSnBatch(row.uuid!);
- message.success(
- $t('ui.actionMessage.deleteSuccess', [row.batchCode || '']),
- );
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- formOptions: {
- schema: useGridFormSchema(),
- },
- gridOptions: {
- columns: useGridColumns(),
- height: 'auto',
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }, formValues) => {
- return await getSnGroupPage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- ...formValues,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'uuid',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- search: true,
- },
- } as VxeTableGridOptions<MesWmSnApi.SnGroup>,
-});
-</script>
-
-<template>
- <Page auto-content-height><FormModal @success="handleRefresh" />
- <DetailModal />
-
- <Grid table-title="SN 鐮佸垪琛�">
- <template #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: '鐢熸垚 SN 鐮�',
- type: 'primary',
- icon: ACTION_ICON.ADD,
- auth: ['mes:wm-sn:create'],
- onClick: handleCreate,
- },
- {
- label: $t('ui.actionTitle.export'),
- type: 'primary',
- icon: ACTION_ICON.DOWNLOAD,
- auth: ['mes:wm-sn:export'],
- onClick: handleExport,
- },
- ]"
- />
- </template>
- <template #count="{ row }">
- <TableAction
- :actions="[
- {
- label: `${row.count ?? 0}`,
- type: 'link',
- auth: ['mes:wm-sn:query'],
- onClick: handleDetail.bind(null, row),
- },
- ]"
- />
- </template>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: '鏌ョ湅鏄庣粏',
- type: 'link',
- auth: ['mes:wm-sn:query'],
- onClick: handleDetail.bind(null, row),
- },
- {
- label: '瀵煎嚭鏄庣粏',
- type: 'link',
- auth: ['mes:wm-sn:export'],
- onClick: handleExportDetail.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- auth: ['mes:wm-sn:delete'],
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [
- row.batchCode || row.itemName,
- ]),
- confirm: handleDelete.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </Page>
-</template>
diff --git a/src/views/sn/modules/detail.vue b/src/views/sn/modules/detail.vue
deleted file mode 100644
index 3ed5e4d..0000000
--- a/src/views/sn/modules/detail.vue
+++ /dev/null
@@ -1,100 +0,0 @@
-<script lang="ts" setup>
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmSnApi } from '#/api/mes/wm/sn';
-
-import { nextTick, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-import { BarcodeBizTypeEnum } from '@vben/constants';
-
-import { message } from 'ant-design-vue';
-
-import { TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import { getSnListByUuid } from '#/api/mes/wm/sn';
-import { BarcodeDetail } from '#/views/wls/barcode/components';
-
-import { useDetailGridColumns } from '../data';
-
-defineOptions({ name: 'MesWmSnDetail' });
-
-const barcodeDetailRef = ref<InstanceType<typeof BarcodeDetail>>();
-
-/** 鏌ョ湅 SN 鐮佹潯鐮� */
-function handleBarcode(row: MesWmSnApi.Sn) {
- if (!row.id) {
- message.warning('缂哄皯 SN 鐮佺紪鍙凤紝鏃犳硶鏌ョ湅鏉$爜');
- return;
- }
- barcodeDetailRef.value?.openByBusiness(
- row.id,
- BarcodeBizTypeEnum.SN,
- row.code,
- row.itemName || row.code,
- );
-}
-
-/** 鍔犺浇 SN 鐮佹槑缁� */
-async function loadDetail(row?: MesWmSnApi.SnGroup) {
- if (!row?.uuid) {
- await gridApi.grid?.loadData([]);
- return;
- }
- gridApi.setLoading(true);
- try {
- const list = await getSnListByUuid(row.uuid);
- await gridApi.grid?.loadData(list);
- } finally {
- gridApi.setLoading(false);
- }
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- gridOptions: {
- columns: useDetailGridColumns(),
- height: 520,
- pagerConfig: {
- enabled: false,
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- enabled: false,
- },
- } as VxeTableGridOptions<MesWmSnApi.Sn>,
-});
-
-const [Modal, modalApi] = useVbenModal({
- showCancelButton: false,
- showConfirmButton: false,
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- await gridApi.grid?.loadData([]);
- return;
- }
- await nextTick();
- await loadDetail(modalApi.getData<MesWmSnApi.SnGroup>());
- },
-});
-</script>
-
-<template>
- <Modal class="w-3/5" title="SN 鐮佹槑缁�">
- <Grid class="mx-4">
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: '鏉$爜',
- type: 'link',
- auth: ['mes:wm-sn:query'],
- onClick: handleBarcode.bind(null, row),
- },
- ]"
- />
- </template>
- </Grid>
- <BarcodeDetail ref="barcodeDetailRef" />
- </Modal>
-</template>
diff --git a/src/views/sn/modules/form.vue b/src/views/sn/modules/form.vue
deleted file mode 100644
index ae66172..0000000
--- a/src/views/sn/modules/form.vue
+++ /dev/null
@@ -1,62 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmSnApi } from '#/api/mes/wm/sn';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import { generateSnCodes } from '#/api/mes/wm/sn';
-import { $t } from '#/locales';
-
-import { useFormSchema } from '../data';
-
-const emit = defineEmits(['success']);
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-2',
- labelWidth: 100,
- },
- layout: 'horizontal',
- schema: useFormSchema(),
- showDefaultActions: false,
-});
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data = (await formApi.getValues()) as MesWmSnApi.SnGenerate;
- try {
- await generateSnCodes(data);
- // 鍏抽棴骞舵彁绀�
- await modalApi.close();
- emit('success');
- message.success('鐢熸垚鎴愬姛');
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- return;
- }
- await formApi.resetForm();
- await formApi.setValues({ count: 100 });
- },
-});
-</script>
-
-<template>
- <Modal :title="$t('ui.actionTitle.create', ['SN 鐮�'])" class="w-1/2">
- <Form class="mx-4" />
- </Modal>
-</template>
diff --git a/src/views/stocktaking/plan/components/condition-value-input.vue b/src/views/stocktaking/plan/components/condition-value-input.vue
deleted file mode 100644
index fedfd1b..0000000
--- a/src/views/stocktaking/plan/components/condition-value-input.vue
+++ /dev/null
@@ -1,204 +0,0 @@
-<script lang="ts" setup>
-import type { NumberDictDataType } from '@vben/hooks';
-
-import { ref, watch } from 'vue';
-
-import { DICT_TYPE, MesWmStockTakingParamTypeEnum } from '@vben/constants';
-import { getDictOptions } from '@vben/hooks';
-
-import { Select } from 'ant-design-vue';
-
-import { getWarehouseArea } from '#/api/mes/wm/warehouse/area';
-import { getWarehouseLocation } from '#/api/mes/wm/warehouse/location';
-import { MdItemSelect } from '#/views/mes/md/item/components';
-import { WmBatchSelect } from '#/views/wls/batch/components';
-import {
- WmWarehouseAreaSelect,
- WmWarehouseLocationSelect,
- WmWarehouseSelect,
-} from '#/views/wls/warehouse/components';
-
-defineOptions({ name: 'StockTakingPlanConditionValueInput' });
-
-const props = withDefaults(
- defineProps<{
- modelValue?: number;
- type?: number;
- valueCode?: string;
- }>(),
- {
- modelValue: undefined,
- type: undefined,
- valueCode: undefined,
- },
-);
-const emit = defineEmits<{
- 'update:modelValue': [value?: number];
- valueChange: [
- payload: { valueCode?: string; valueId?: number; valueName?: string },
- ];
-}>();
-
-const qualityStatusOptions = getDictOptions(
- DICT_TYPE.MES_WM_QUALITY_STATUS,
- 'number',
-) as NumberDictDataType[];
-
-const locationWarehouseId = ref<number>(); // 搴撳尯閫夋嫨鍣ㄤ复鏃舵暟鎹細閫変粨搴撳悗浼犵粰搴撳尯閫夋嫨鍣�
-const areaWarehouseId = ref<number>(); // 搴撲綅閫夋嫨鍣ㄤ复鏃舵暟鎹細閫変粨搴撳悗浼犵粰搴撳尯閫夋嫨鍣�
-const areaLocationId = ref<number>(); // 搴撲綅閫夋嫨鍣ㄤ复鏃舵暟鎹細閫夊簱鍖哄悗浼犵粰搴撲綅閫夋嫨鍣�
-
-const qualityStatusValue = ref<number>();
-
-/** 閫氱敤閫夋嫨鍣ㄥ彉鍖栵細鍥炲~鏉′欢鍊肩紪鐮併�佸悕绉� */
-function handleSelectorChange(item?: any) {
- emit('update:modelValue', item?.id);
- emit('valueChange', {
- valueId: item?.id,
- valueCode: item?.code || '',
- valueName: item?.name || item?.nickname || '',
- });
-}
-
-/** 鎵规閫夋嫨鍣ㄥ彉鍖� */
-function handleBatchChange(batch?: any) {
- emit('update:modelValue', batch?.id);
- emit('valueChange', {
- valueId: batch?.id,
- valueCode: batch?.code || '',
- valueName: batch?.code || '',
- });
-}
-
-/** 璐ㄩ噺鐘舵�侀�夋嫨鍣ㄥ彉鍖栵細鏃犲疄浣撶紪鍙凤紝浠呰褰曞瓧鍏哥紪鐮佸拰鏂囨 */
-function handleQualityStatusChange(value?: number) {
- qualityStatusValue.value = value;
- const selected = qualityStatusOptions.find((item) => item.value === value);
- emit('update:modelValue', undefined);
- emit('valueChange', {
- valueId: undefined,
- valueCode: value === null ? '' : String(value),
- valueName: selected?.label || '',
- });
-}
-
-/** 搴撳尯浠撳簱閫夋嫨鍥炶皟锛氭竻绌哄簱鍖� */
-function handleLocationWarehouseChange() {
- emit('update:modelValue', undefined);
- emit('valueChange', { valueId: undefined, valueCode: '', valueName: '' });
-}
-
-/** 搴撲綅浠撳簱閫夋嫨鍥炶皟锛氭竻绌哄簱鍖哄拰搴撲綅 */
-function handleAreaWarehouseChange() {
- areaLocationId.value = undefined;
- emit('update:modelValue', undefined);
- emit('valueChange', { valueId: undefined, valueCode: '', valueName: '' });
-}
-
-/** 搴撲綅搴撳尯閫夋嫨鍥炶皟锛氭竻绌哄簱浣� */
-function handleAreaLocationChange() {
- emit('update:modelValue', undefined);
- emit('valueChange', { valueId: undefined, valueCode: '', valueName: '' });
-}
-
-/** 缂栬緫鏃跺洖濉骇鑱旈�夋嫨鍣ㄧ殑涓婄骇鏁版嵁锛堝簱鍖烘墍灞炰粨搴撱�佸簱浣嶆墍灞炰粨搴�/搴撳尯锛� */
-async function loadCascadeData() {
- if (props.type === MesWmStockTakingParamTypeEnum.QUALITY_STATUS) {
- qualityStatusValue.value = props.valueCode
- ? Number(props.valueCode)
- : undefined;
- return;
- }
- if (!props.modelValue) {
- return;
- }
- if (props.type === MesWmStockTakingParamTypeEnum.LOCATION) {
- const location = await getWarehouseLocation(props.modelValue);
- locationWarehouseId.value = location?.warehouseId;
- } else if (props.type === MesWmStockTakingParamTypeEnum.AREA) {
- const area = await getWarehouseArea(props.modelValue);
- areaWarehouseId.value = area?.warehouseId;
- areaLocationId.value = area?.locationId;
- }
-}
-
-// 鏉′欢绫诲瀷鍙樺寲鏃堕噸缃骇鑱斾复鏃舵暟鎹紱缂栬緫鍥炴樉鏃舵寜绫诲瀷鍔犺浇涓婄骇鏁版嵁
-watch(
- () => props.type,
- () => {
- locationWarehouseId.value = undefined;
- areaWarehouseId.value = undefined;
- areaLocationId.value = undefined;
- qualityStatusValue.value = undefined;
- void loadCascadeData();
- },
- { immediate: true },
-);
-</script>
-
-<template>
- <WmWarehouseSelect
- v-if="type === MesWmStockTakingParamTypeEnum.WAREHOUSE"
- :model-value="modelValue"
- @change="handleSelectorChange"
- />
- <div
- v-else-if="type === MesWmStockTakingParamTypeEnum.LOCATION"
- class="space-y-2"
- >
- <WmWarehouseSelect
- v-model="locationWarehouseId"
- placeholder="璇烽�夋嫨浠撳簱"
- @change="handleLocationWarehouseChange"
- />
- <WmWarehouseLocationSelect
- v-if="locationWarehouseId"
- :model-value="modelValue"
- :warehouse-id="locationWarehouseId"
- placeholder="璇烽�夋嫨搴撳尯"
- @change="handleSelectorChange"
- />
- </div>
- <div
- v-else-if="type === MesWmStockTakingParamTypeEnum.AREA"
- class="space-y-2"
- >
- <WmWarehouseSelect
- v-model="areaWarehouseId"
- placeholder="璇烽�夋嫨浠撳簱"
- @change="handleAreaWarehouseChange"
- />
- <WmWarehouseLocationSelect
- v-if="areaWarehouseId"
- v-model="areaLocationId"
- placeholder="璇烽�夋嫨搴撳尯"
- :warehouse-id="areaWarehouseId"
- @change="handleAreaLocationChange"
- />
- <WmWarehouseAreaSelect
- v-if="areaLocationId"
- :model-value="modelValue"
- :location-id="areaLocationId"
- placeholder="璇烽�夋嫨搴撲綅"
- @change="handleSelectorChange"
- />
- </div>
- <MdItemSelect
- v-else-if="type === MesWmStockTakingParamTypeEnum.ITEM"
- :model-value="modelValue"
- @change="handleSelectorChange"
- />
- <WmBatchSelect
- v-else-if="type === MesWmStockTakingParamTypeEnum.BATCH"
- :model-value="modelValue"
- @change="handleBatchChange"
- />
- <Select
- v-else-if="type === MesWmStockTakingParamTypeEnum.QUALITY_STATUS"
- :options="qualityStatusOptions"
- :value="qualityStatusValue"
- placeholder="璇烽�夋嫨璐ㄩ噺鐘舵��"
- class="w-full"
- @change="(value) => handleQualityStatusChange(value as number)"
- />
-</template>
diff --git a/src/views/stocktaking/plan/components/index.ts b/src/views/stocktaking/plan/components/index.ts
deleted file mode 100644
index 2d492d0..0000000
--- a/src/views/stocktaking/plan/components/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export { default as StockTakingPlanConditionValueInput } from './condition-value-input.vue';
-export { default as StockTakingPlanSelectDialog } from './select-dialog.vue';
-export { default as StockTakingPlanSelect } from './select.vue';
diff --git a/src/views/stocktaking/plan/components/select.vue b/src/views/stocktaking/plan/components/select.vue
deleted file mode 100644
index 7f56f67..0000000
--- a/src/views/stocktaking/plan/components/select.vue
+++ /dev/null
@@ -1,135 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmStockTakingPlanApi } from '#/api/mes/wm/stocktaking/plan';
-
-import { computed, ref, useAttrs, watch } from 'vue';
-
-import { IconifyIcon } from '@vben/icons';
-
-import { Input, Tooltip } from 'ant-design-vue';
-
-import { getStockTakingPlan } from '#/api/mes/wm/stocktaking/plan';
-
-import StockTakingPlanSelectDialog from './select-dialog.vue';
-
-defineOptions({ name: 'StockTakingPlanSelect', inheritAttrs: false });
-
-const props = withDefaults(
- defineProps<{
- allowClear?: boolean;
- disabled?: boolean;
- modelValue?: number;
- placeholder?: string;
- }>(),
- {
- allowClear: true,
- disabled: false,
- modelValue: undefined,
- placeholder: '璇烽�夋嫨鐩樼偣鏂规',
- },
-);
-
-const emit = defineEmits<{
- change: [item: MesWmStockTakingPlanApi.StockTakingPlan | undefined];
- 'update:modelValue': [value: number | undefined];
-}>();
-
-const attrs = useAttrs();
-const dialogRef = ref<InstanceType<typeof StockTakingPlanSelectDialog>>();
-const hovering = ref(false);
-const selectedItem = ref<MesWmStockTakingPlanApi.StockTakingPlan>();
-
-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) {
- selectedItem.value = undefined;
- return;
- }
- if (selectedItem.value?.id === id) {
- return;
- }
- selectedItem.value = await getStockTakingPlan(id);
-}
-
-watch(() => props.modelValue, resolveItemById, { 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]
- ) as number[];
- dialogRef.value?.open(selectedIds, { multiple: false });
-}
-
-/** 寮圭獥閫変腑鍥炶皟 */
-function handleSelected(rows: MesWmStockTakingPlanApi.StockTakingPlan[]) {
- const item = rows[0];
- if (!item) {
- return;
- }
- selectedItem.value = item;
- emit('update:modelValue', item.id);
- emit('change', item);
-}
-</script>
-
-<template>
- <div
- v-bind="attrs"
- class="w-full"
- :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>鏄惁鐩茬洏锛歿{ selectedItem.blindFlag ? '鏄�' : '鍚�' }}</div>
- <div>鏄惁鍐荤粨搴撳瓨锛歿{ selectedItem.frozen ? '鏄�' : '鍚�' }}</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>
- <StockTakingPlanSelectDialog ref="dialogRef" @selected="handleSelected" />
-</template>
diff --git a/src/views/stocktaking/plan/data.ts b/src/views/stocktaking/plan/data.ts
deleted file mode 100644
index f095437..0000000
--- a/src/views/stocktaking/plan/data.ts
+++ /dev/null
@@ -1,472 +0,0 @@
-import type { NumberDictDataType } from '@vben/hooks';
-
-import type { VbenFormApi, VbenFormSchema } from '#/adapter/form';
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmStockTakingPlanApi } from '#/api/mes/wm/stocktaking/plan';
-import type { MesWmStockTakingPlanParamApi } from '#/api/mes/wm/stocktaking/plan/param';
-
-import { h, markRaw } from 'vue';
-
-import {
- CommonStatusEnum,
- DICT_TYPE,
- MesAutoCodeRuleCode,
- MesWmStockTakingTypeEnum,
-} from '@vben/constants';
-import { getDictOptions } from '@vben/hooks';
-
-import { Button } from 'ant-design-vue';
-
-import { z } from '#/adapter/form';
-import { generateAutoCode } from '#/api/mes/md/autocode/record';
-
-import { StockTakingPlanConditionValueInput } from './components';
-
-/** 琛ㄥ崟绫诲瀷 */
-export type FormType = 'create' | 'detail' | 'update';
-
-/** 鏂板/淇敼鐨勮〃鍗� */
-export function useFormSchema(
- formType: FormType,
- formApi?: VbenFormApi,
-): VbenFormSchema[] {
- return [
- {
- fieldName: 'id',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'code',
- label: '鏂规缂栫爜',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ユ柟妗堢紪鐮�',
- },
- rules: 'required',
- suffix:
- formType === 'detail'
- ? undefined
- : () =>
- h(
- Button,
- {
- type: 'default',
- onClick: async () => {
- const code = await generateAutoCode(
- MesAutoCodeRuleCode.WM_STOCK_TAKING_PLAN_CODE,
- );
- await formApi?.setFieldValue('code', code);
- },
- },
- { default: () => '鐢熸垚' },
- ),
- },
- {
- fieldName: 'name',
- label: '鏂规鍚嶇О',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ユ柟妗堝悕绉�',
- },
- rules: 'required',
- },
- {
- fieldName: 'type',
- label: '鐩樼偣绫诲瀷',
- component: 'Select',
- componentProps: {
- options: getDictOptions(DICT_TYPE.MES_WM_STOCK_TAKING_TYPE, 'number'),
- placeholder: '璇烽�夋嫨鐩樼偣绫诲瀷',
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'startTime',
- label: '寮�濮嬫椂闂�',
- component: 'DatePicker',
- componentProps: {
- placeholder: '璇烽�夋嫨寮�濮嬫椂闂�',
- showTime: true,
- valueFormat: 'x',
- },
- dependencies: {
- triggerFields: ['type'],
- show: (values) => values.type === MesWmStockTakingTypeEnum.DYNAMIC,
- },
- },
- {
- fieldName: 'endTime',
- label: '缁撴潫鏃堕棿',
- component: 'DatePicker',
- componentProps: {
- placeholder: '璇烽�夋嫨缁撴潫鏃堕棿',
- showTime: true,
- valueFormat: 'x',
- },
- dependencies: {
- triggerFields: ['type'],
- show: (values) => values.type === MesWmStockTakingTypeEnum.DYNAMIC,
- },
- },
- {
- fieldName: 'blindFlag',
- label: '鏄惁鐩茬洏',
- component: 'Switch',
- componentProps: {
- checkedChildren: '鏄�',
- unCheckedChildren: '鍚�',
- },
- rules: z.boolean().default(false),
- },
- {
- fieldName: 'frozen',
- label: '鍐荤粨搴撳瓨',
- component: 'Switch',
- componentProps: {
- checkedChildren: '鏄�',
- unCheckedChildren: '鍚�',
- },
- rules: z.boolean().default(false),
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勬悳绱㈣〃鍗� */
-export function useGridFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'code',
- label: '鏂规缂栫爜',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ユ柟妗堢紪鐮�',
- },
- },
- {
- fieldName: 'name',
- label: '鏂规鍚嶇О',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ユ柟妗堝悕绉�',
- },
- },
- {
- fieldName: 'type',
- label: '鐩樼偣绫诲瀷',
- component: 'Select',
- componentProps: {
- allowClear: true,
- options: getDictOptions(DICT_TYPE.MES_WM_STOCK_TAKING_TYPE, 'number'),
- placeholder: '璇烽�夋嫨鐩樼偣绫诲瀷',
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勫瓧娈� */
-export function useGridColumns(
- onStatusChange?: (
- newStatus: number,
- row: MesWmStockTakingPlanApi.StockTakingPlan,
- ) => Promise<boolean | undefined>,
-): VxeTableGridOptions<MesWmStockTakingPlanApi.StockTakingPlan>['columns'] {
- return [
- {
- field: 'code',
- title: '鏂规缂栫爜',
- minWidth: 160,
- slots: { default: 'code' },
- },
- {
- field: 'name',
- title: '鏂规鍚嶇О',
- minWidth: 160,
- },
- {
- field: 'type',
- title: '鐩樼偣绫诲瀷',
- minWidth: 120,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_STOCK_TAKING_TYPE },
- },
- },
- {
- field: 'startTime',
- title: '寮�濮嬫椂闂�',
- width: 180,
- formatter: 'formatDateTime',
- },
- {
- field: 'endTime',
- title: '缁撴潫鏃堕棿',
- width: 180,
- formatter: 'formatDateTime',
- },
- {
- field: 'blindFlag',
- title: '鏄惁鐩茬洏',
- width: 100,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.INFRA_BOOLEAN_STRING },
- },
- },
- {
- field: 'frozen',
- title: '鏄惁鍐荤粨搴撳瓨',
- width: 120,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.INFRA_BOOLEAN_STRING },
- },
- },
- {
- field: 'status',
- title: '鐘舵��',
- width: 120,
- cellRender: {
- attrs: { beforeChange: onStatusChange },
- name: 'CellSwitch',
- props: {
- checkedValue: CommonStatusEnum.ENABLE,
- unCheckedValue: CommonStatusEnum.DISABLE,
- },
- },
- },
- {
- title: '鎿嶄綔',
- width: 160,
- fixed: 'right',
- slots: { default: 'actions' },
- },
- ];
-}
-
-/** 鐩樼偣鏂规鏉′欢鍒楄〃鐨勫瓧娈� */
-export function useParamGridColumns(
- editable = true,
-): VxeTableGridOptions<MesWmStockTakingPlanParamApi.StockTakingPlanParam>['columns'] {
- return [
- {
- field: 'type',
- title: '鏉′欢绫诲瀷',
- minWidth: 120,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_STOCK_TAKING_PLAN_PARAM_TYPE },
- },
- },
- {
- field: 'valueCode',
- title: '鏉′欢鍊肩紪鐮�',
- minWidth: 140,
- },
- {
- field: 'valueName',
- title: '鏉′欢鍊煎悕绉�',
- minWidth: 160,
- },
- ...(editable
- ? [
- {
- title: '鎿嶄綔',
- width: 120,
- fixed: 'right',
- slots: { default: 'actions' },
- } as const,
- ]
- : []),
- ];
-}
-
-/** 鐩樼偣鏂规鏉′欢琛ㄥ崟 schema */
-export function useParamFormSchema(formApi?: VbenFormApi): VbenFormSchema[] {
- return [
- {
- fieldName: 'type',
- label: '鏉′欢绫诲瀷',
- component: 'Select',
- componentProps: {
- options: getDictOptions(
- DICT_TYPE.MES_WM_STOCK_TAKING_PLAN_PARAM_TYPE,
- 'number',
- ) as NumberDictDataType[],
- placeholder: '璇烽�夋嫨鏉′欢绫诲瀷',
- // 鏉′欢绫诲瀷鍙樺寲锛氭竻绌哄凡閫夋潯浠跺�硷紝閬垮厤娈嬬暀鏃х被鍨嬬殑鏉′欢鍊�
- onChange: async () => {
- await formApi?.setValues({
- valueCode: '',
- valueId: undefined,
- valueName: '',
- });
- },
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'valueId',
- label: '鏉′欢鍊�',
- component: markRaw(StockTakingPlanConditionValueInput),
- // 鏉′欢鍊兼帶浠跺唴閮ㄦ寜鏉′欢绫诲瀷鍒囨崲閫夋嫨鍣紝浠呴�夋嫨绫诲瀷鍚庡睍绀�
- dependencies: {
- triggerFields: ['type'],
- if: (values) => values.type !== null,
- componentProps: (values) => ({
- type: values.type,
- valueCode: values.valueCode,
- // 鏉′欢鍊兼帶浠跺洖濉� valueId / valueCode / valueName
- onValueChange: async (payload: {
- valueCode?: string;
- valueId?: number;
- valueName?: string;
- }) => {
- await formApi?.setValues({
- valueCode: payload.valueCode ?? '',
- valueId: payload.valueId,
- valueName: payload.valueName ?? '',
- });
- },
- }),
- },
- },
- {
- // 鏉′欢鍊肩紪鐮侊細鐢辨潯浠跺�兼帶浠跺洖鍐欙紝闅愯棌瀛楁
- fieldName: 'valueCode',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- // 鏉′欢鍊煎悕绉帮細鐢辨潯浠跺�兼帶浠跺洖鍐欙紝闅愯棌瀛楁
- fieldName: 'valueName',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
-
-/** 閫夋嫨寮圭獥鐨勬悳绱㈣〃鍗� */
-export function useSelectGridFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'code',
- label: '鏂规缂栫爜',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ユ柟妗堢紪鐮�',
- },
- },
- {
- fieldName: 'name',
- label: '鏂规鍚嶇О',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ユ柟妗堝悕绉�',
- },
- },
- {
- fieldName: 'type',
- label: '鐩樼偣绫诲瀷',
- component: 'Select',
- componentProps: {
- allowClear: true,
- options: getDictOptions(DICT_TYPE.MES_WM_STOCK_TAKING_TYPE, 'number'),
- placeholder: '璇烽�夋嫨鐩樼偣绫诲瀷',
- },
- },
- ];
-}
-
-/** 閫夋嫨寮圭獥鐨勫瓧娈� */
-export function useSelectGridColumns(
- multiple = true,
-): VxeTableGridOptions<MesWmStockTakingPlanApi.StockTakingPlan>['columns'] {
- return [
- {
- type: multiple ? 'checkbox' : 'radio',
- width: 50,
- },
- {
- field: 'code',
- title: '鏂规缂栫爜',
- width: 200,
- },
- {
- field: 'name',
- title: '鏂规鍚嶇О',
- minWidth: 150,
- },
- {
- field: 'type',
- title: '鐩樼偣绫诲瀷',
- width: 120,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_STOCK_TAKING_TYPE },
- },
- },
- {
- field: 'startTime',
- title: '寮�濮嬫椂闂�',
- width: 180,
- formatter: 'formatDateTime',
- },
- {
- field: 'endTime',
- title: '缁撴潫鏃堕棿',
- width: 180,
- formatter: 'formatDateTime',
- },
- {
- field: 'blindFlag',
- title: '鏄惁鐩茬洏',
- width: 100,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.INFRA_BOOLEAN_STRING },
- },
- },
- {
- field: 'frozen',
- title: '鏄惁鍐荤粨搴撳瓨',
- width: 120,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.INFRA_BOOLEAN_STRING },
- },
- },
- ];
-}
diff --git a/src/views/stocktaking/plan/index.vue b/src/views/stocktaking/plan/index.vue
deleted file mode 100644
index 5a76054..0000000
--- a/src/views/stocktaking/plan/index.vue
+++ /dev/null
@@ -1,176 +0,0 @@
-<script lang="ts" setup>
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmStockTakingPlanApi } from '#/api/mes/wm/stocktaking/plan';
-
-import { confirm, Page, useVbenModal } from '@vben/common-ui';
-import { CommonStatusEnum } from '@vben/constants';
-import { downloadFileFromBlobPart } from '@vben/utils';
-
-import { Button, message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import {
- deleteStockTakingPlan,
- exportStockTakingPlan,
- getStockTakingPlanPage,
- updateStockTakingPlanStatus,
-} from '#/api/mes/wm/stocktaking/plan';
-import { $t } from '#/locales';
-
-import { useGridColumns, useGridFormSchema } from './data';
-import Form from './modules/form.vue';
-
-const [FormModal, formModalApi] = useVbenModal({
- connectedComponent: Form,
- destroyOnClose: true,
-});
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- gridApi.query();
-}
-
-/** 鍒涘缓鐩樼偣鏂规 */
-function handleCreate() {
- formModalApi.setData({ formType: 'create' }).open();
-}
-
-/** 鏌ョ湅鐩樼偣鏂规 */
-function handleDetail(row: MesWmStockTakingPlanApi.StockTakingPlan) {
- formModalApi.setData({ formType: 'detail', id: row.id }).open();
-}
-
-/** 缂栬緫鐩樼偣鏂规 */
-function handleEdit(row: MesWmStockTakingPlanApi.StockTakingPlan) {
- formModalApi.setData({ formType: 'update', id: row.id }).open();
-}
-
-/** 鏇存柊鐩樼偣鏂规鐘舵�� */
-async function handleStatusChange(
- newStatus: number,
- row: MesWmStockTakingPlanApi.StockTakingPlan,
-): Promise<boolean | undefined> {
- try {
- await confirm(
- `纭瑕�${newStatus === CommonStatusEnum.ENABLE ? '鍚敤' : '鍋滅敤'}"${row.name}"鐩樼偣鏂规鍚楋紵`,
- );
- } catch {
- return false;
- }
- await updateStockTakingPlanStatus(row.id!, newStatus);
- message.success($t('ui.actionMessage.operationSuccess'));
- return true;
-}
-
-/** 鍒犻櫎鐩樼偣鏂规 */
-async function handleDelete(row: MesWmStockTakingPlanApi.StockTakingPlan) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.name]),
- duration: 0,
- });
- try {
- await deleteStockTakingPlan(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.name]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-/** 瀵煎嚭琛ㄦ牸 */
-async function handleExport() {
- const data = await exportStockTakingPlan(await gridApi.formApi.getValues());
- downloadFileFromBlobPart({ fileName: '鐩樼偣鏂规.xls', source: data });
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- formOptions: {
- schema: useGridFormSchema(),
- },
- gridOptions: {
- columns: useGridColumns(handleStatusChange),
- height: 'auto',
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }, formValues) => {
- return await getStockTakingPlanPage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- ...formValues,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- search: true,
- },
- } as VxeTableGridOptions<MesWmStockTakingPlanApi.StockTakingPlan>,
-});
-
-const StatusEnum = CommonStatusEnum;
-</script>
-
-<template>
- <Page auto-content-height><FormModal @success="handleRefresh" />
-
- <Grid table-title="鐩樼偣鏂规鍒楄〃">
- <template #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: $t('ui.actionTitle.create', ['鐩樼偣鏂规']),
- type: 'primary',
- icon: ACTION_ICON.ADD,
- auth: ['mes:wm-stock-taking-plan:create'],
- onClick: handleCreate,
- },
- {
- label: $t('ui.actionTitle.export'),
- type: 'primary',
- icon: ACTION_ICON.DOWNLOAD,
- auth: ['mes:wm-stock-taking-plan:export'],
- onClick: handleExport,
- },
- ]"
- />
- </template>
- <template #code="{ row }">
- <Button type="link" @click="handleDetail(row)">
- {{ row.code }}
- </Button>
- </template>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- auth: ['mes:wm-stock-taking-plan:update'],
- disabled: row.status !== StatusEnum.DISABLE,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- auth: ['mes:wm-stock-taking-plan:delete'],
- disabled: row.status !== StatusEnum.DISABLE,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.name]),
- confirm: handleDelete.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </Page>
-</template>
diff --git a/src/views/stocktaking/plan/modules/form.vue b/src/views/stocktaking/plan/modules/form.vue
deleted file mode 100644
index f0e7827..0000000
--- a/src/views/stocktaking/plan/modules/form.vue
+++ /dev/null
@@ -1,126 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { MesWmStockTakingPlanApi } from '#/api/mes/wm/stocktaking/plan';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { Divider, message } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createStockTakingPlan,
- getStockTakingPlan,
- updateStockTakingPlan,
-} from '#/api/mes/wm/stocktaking/plan';
-import { $t } from '#/locales';
-
-import { useFormSchema } from '../data';
-import ParamList from './param-list.vue';
-
-const emit = defineEmits(['success']);
-const formType = ref<FormType>('create');
-const formData = ref<MesWmStockTakingPlanApi.StockTakingPlan>();
-const isDetail = computed(() => formType.value === 'detail');
-const showParam = computed(
- () =>
- (formType.value === 'detail' || formType.value === 'update') &&
- !!formData.value?.id,
-);
-const getTitle = computed(() => {
- if (formType.value === 'detail') {
- return $t('ui.actionTitle.view', ['鐩樼偣鏂规']);
- }
- return formType.value === 'update'
- ? $t('ui.actionTitle.edit', ['鐩樼偣鏂规'])
- : $t('ui.actionTitle.create', ['鐩樼偣鏂规']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 110,
- },
- layout: 'horizontal',
- schema: [],
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- if (isDetail.value) {
- await modalApi.close();
- return;
- }
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data =
- (await formApi.getValues()) as MesWmStockTakingPlanApi.StockTakingPlan;
- try {
- if (formData.value?.id) {
- await updateStockTakingPlan({ ...data, id: formData.value.id });
- // 鍏抽棴骞舵彁绀�
- await modalApi.close();
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } else {
- // 鏂板鎴愬姛鍚庡垏鎹负缂栬緫鎬侊紝缁х画缁存姢鐩樼偣鍙傛暟
- const id = await createStockTakingPlan(data);
- formData.value = { ...data, id };
- await formApi.setFieldValue('id', id);
- formType.value = 'update';
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- }
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- return;
- }
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{ formType: FormType; id?: number }>();
- formType.value = data.formType;
- formApi.setState({ schema: useFormSchema(formType.value, formApi) });
- formApi.setDisabled(formType.value === 'detail');
- modalApi.setState({ showConfirmButton: formType.value !== 'detail' });
- if (!data?.id) {
- return;
- }
- modalApi.lock();
- try {
- formData.value = await getStockTakingPlan(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- <!-- 缂栬緫鎴栬鎯呮椂灞曠ず鐩樼偣鍙傛暟 -->
- <template v-if="showParam">
- <Divider>鐩樼偣鍙傛暟</Divider>
- <div class="mx-4">
- <ParamList :disabled="isDetail" :plan-id="formData!.id!" />
- </div>
- </template>
- </Modal>
-</template>
diff --git a/src/views/stocktaking/plan/modules/param-form.vue b/src/views/stocktaking/plan/modules/param-form.vue
deleted file mode 100644
index d4c171b..0000000
--- a/src/views/stocktaking/plan/modules/param-form.vue
+++ /dev/null
@@ -1,108 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmStockTakingPlanParamApi } from '#/api/mes/wm/stocktaking/plan/param';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-import { MesWmStockTakingParamTypeEnum } from '@vben/constants';
-
-import { message } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createStockTakingPlanParam,
- getStockTakingPlanParam,
- updateStockTakingPlanParam,
-} from '#/api/mes/wm/stocktaking/plan/param';
-import { $t } from '#/locales';
-
-import { useParamFormSchema } from '../data';
-
-const emit = defineEmits(['success']);
-const formId = ref<number>(); // 褰撳墠缂栬緫鐨勬潯浠剁紪鍙�
-const planId = ref<number>(); // 鎵�灞炵洏鐐规柟妗堢紪鍙�
-
-const getTitle = computed(() =>
- formId.value
- ? $t('ui.actionTitle.edit', ['鐩樼偣鏉′欢'])
- : $t('ui.actionTitle.create', ['鐩樼偣鏉′欢']),
-);
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- },
- layout: 'horizontal',
- schema: [],
- showDefaultActions: false,
- wrapperClass: 'grid-cols-1',
-});
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- const values =
- (await formApi.getValues()) as MesWmStockTakingPlanParamApi.StockTakingPlanParam;
- // 璐ㄩ噺鐘舵�佹牎楠� valueCode锛屽叾浣欑被鍨嬫牎楠� valueId
- const valueValid =
- values.type === MesWmStockTakingParamTypeEnum.QUALITY_STATUS
- ? !!values.valueCode
- : values.valueId !== null;
- if (!valueValid) {
- message.warning('璇烽�夋嫨鏉′欢鍊�');
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data = {
- ...values,
- id: formId.value,
- planId: planId.value,
- } as MesWmStockTakingPlanParamApi.StockTakingPlanParam;
- try {
- await (formId.value
- ? updateStockTakingPlanParam(data)
- : createStockTakingPlanParam(data));
- // 鍏抽棴骞舵彁绀�
- await modalApi.close();
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formId.value = undefined;
- return;
- }
- formApi.setState({ schema: useParamFormSchema(formApi) });
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{ id?: number; planId: number }>();
- planId.value = data.planId;
- formId.value = data.id;
- if (!data.id) {
- return;
- }
- modalApi.lock();
- try {
- const param = await getStockTakingPlanParam(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(param);
- } finally {
- modalApi.unlock();
- }
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- </Modal>
-</template>
diff --git a/src/views/stocktaking/plan/modules/param-list.vue b/src/views/stocktaking/plan/modules/param-list.vue
deleted file mode 100644
index 47df098..0000000
--- a/src/views/stocktaking/plan/modules/param-list.vue
+++ /dev/null
@@ -1,131 +0,0 @@
-<script lang="ts" setup>
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmStockTakingPlanParamApi } from '#/api/mes/wm/stocktaking/plan/param';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import {
- deleteStockTakingPlanParam,
- getStockTakingPlanParamPage,
-} from '#/api/mes/wm/stocktaking/plan/param';
-import { $t } from '#/locales';
-
-import { useParamGridColumns } from '../data';
-import ParamForm from './param-form.vue';
-
-const props = defineProps<{
- disabled: boolean; // 鏄惁鍙锛堣鎯呮�侊級
- planId: number; // 鎵�灞炴柟妗堢紪鍙�
-}>();
-
-const [ParamFormModal, paramFormModalApi] = useVbenModal({
- connectedComponent: ParamForm,
- destroyOnClose: true,
-});
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- gridApi.query();
-}
-
-/** 娣诲姞鏉′欢 */
-function handleCreate() {
- paramFormModalApi.setData({ planId: props.planId }).open();
-}
-
-/** 缂栬緫鏉′欢 */
-function handleEdit(row: MesWmStockTakingPlanParamApi.StockTakingPlanParam) {
- paramFormModalApi.setData({ id: row.id, planId: props.planId }).open();
-}
-
-/** 鍒犻櫎鏉′欢 */
-async function handleDelete(
- row: MesWmStockTakingPlanParamApi.StockTakingPlanParam,
-) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.valueName]),
- duration: 0,
- });
- try {
- await deleteStockTakingPlanParam(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.valueName]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- gridOptions: {
- columns: useParamGridColumns(!props.disabled),
- height: 320,
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }) => {
- if (!props.planId) {
- return { list: [], total: 0 };
- }
- return await getStockTakingPlanParamPage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- planId: props.planId,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- },
- } as VxeTableGridOptions<MesWmStockTakingPlanParamApi.StockTakingPlanParam>,
-});
-</script>
-
-<template>
- <div>
- <ParamFormModal @success="handleRefresh" />
- <Grid table-title="鐩樼偣鍙傛暟">
- <template v-if="!disabled" #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: '娣诲姞鏉′欢',
- type: 'primary',
- icon: ACTION_ICON.ADD,
- onClick: handleCreate,
- },
- ]"
- />
- </template>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.valueName]),
- confirm: handleDelete.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </div>
-</template>
diff --git a/src/views/stocktaking/task/data.ts b/src/views/stocktaking/task/data.ts
deleted file mode 100644
index 1d17cc9..0000000
--- a/src/views/stocktaking/task/data.ts
+++ /dev/null
@@ -1,600 +0,0 @@
-import type { VbenFormApi, VbenFormSchema } from '#/adapter/form';
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmStockTakingPlanApi } from '#/api/mes/wm/stocktaking/plan';
-import type { MesWmStockTakingTaskApi } from '#/api/mes/wm/stocktaking/task';
-import type { MesWmStockTakingTaskLineApi } from '#/api/mes/wm/stocktaking/task/line';
-import type { MesWmStockTakingResultApi } from '#/api/mes/wm/stocktaking/task/result';
-
-import { h, markRaw } from 'vue';
-
-import {
- DICT_TYPE,
- MesAutoCodeRuleCode,
- MesWmStockTakingTypeEnum,
-} from '@vben/constants';
-import { getDictOptions } from '@vben/hooks';
-
-import { Button } from 'ant-design-vue';
-
-import { z } from '#/adapter/form';
-import { generateAutoCode } from '#/api/mes/md/autocode/record';
-import { getSimpleUserList } from '#/api/system/user';
-import { getRangePickerDefaultProps } from '#/utils';
-import { MdItemSelect } from '#/views/mes/md/item/components';
-import { StockTakingPlanSelect } from '#/views/wls/stocktaking/plan/components';
-import {
- WmWarehouseAreaSelect,
- WmWarehouseLocationSelect,
- WmWarehouseSelect,
-} from '#/views/wls/warehouse/components';
-
-/** 琛ㄥ崟绫诲瀷 */
-export type FormType = 'create' | 'detail' | 'execute' | 'submit' | 'update';
-
-/** 琛ㄥ崟澶撮儴鏄惁鍙锛堟彁浜ゃ�佹墽琛岀洏鐐广�佽鎯呮�侊級 */
-function isHeaderReadonly(formType: FormType): boolean {
- return (
- formType === 'detail' || formType === 'execute' || formType === 'submit'
- );
-}
-
-/** 鏂板/淇敼鐨勮〃鍗� */
-export function useFormSchema(
- formType: FormType,
- formApi?: VbenFormApi,
-): VbenFormSchema[] {
- const headerReadonly = isHeaderReadonly(formType);
- return [
- {
- fieldName: 'id',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'status',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'code',
- label: '浠诲姟缂栫爜',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ヤ换鍔$紪鐮�',
- },
- rules: 'required',
- suffix: headerReadonly
- ? undefined
- : () =>
- h(
- Button,
- {
- type: 'default',
- onClick: async () => {
- const code = await generateAutoCode(
- MesAutoCodeRuleCode.WM_STOCK_TAKING_CODE,
- );
- await formApi?.setFieldValue('code', code);
- },
- },
- { default: () => '鐢熸垚' },
- ),
- },
- {
- fieldName: 'name',
- label: '浠诲姟鍚嶇О',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ヤ换鍔″悕绉�',
- },
- rules: 'required',
- },
- {
- fieldName: 'planId',
- label: '鐩樼偣鏂规',
- component: markRaw(StockTakingPlanSelect),
- componentProps: {
- // 閫夋嫨鐩樼偣鏂规鍚庯紝鑷姩甯﹀嚭鍚嶇О銆佺被鍨嬨�佽捣姝㈡椂闂村拰鐩茬洏/鍐荤粨閰嶇疆
- onChange: async (plan?: MesWmStockTakingPlanApi.StockTakingPlan) => {
- if (!plan) {
- return;
- }
- await formApi?.setValues({
- blindFlag: !!plan.blindFlag,
- endTime: plan.endTime,
- frozen: !!plan.frozen,
- name: plan.name,
- startTime: plan.startTime,
- type: plan.type,
- });
- },
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'type',
- label: '鐩樼偣绫诲瀷',
- component: 'Select',
- componentProps: {
- options: getDictOptions(DICT_TYPE.MES_WM_STOCK_TAKING_TYPE, 'number'),
- placeholder: '璇烽�夋嫨鐩樼偣绫诲瀷',
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'startTime',
- label: '寮�濮嬫椂闂�',
- component: 'DatePicker',
- componentProps: {
- placeholder: '璇烽�夋嫨寮�濮嬫椂闂�',
- showTime: true,
- valueFormat: 'x',
- },
- dependencies: {
- triggerFields: ['type'],
- show: (values) => values.type === MesWmStockTakingTypeEnum.DYNAMIC,
- },
- },
- {
- fieldName: 'endTime',
- label: '缁撴潫鏃堕棿',
- component: 'DatePicker',
- componentProps: {
- placeholder: '璇烽�夋嫨缁撴潫鏃堕棿',
- showTime: true,
- valueFormat: 'x',
- },
- dependencies: {
- triggerFields: ['type'],
- show: (values) => values.type === MesWmStockTakingTypeEnum.DYNAMIC,
- },
- },
- {
- fieldName: 'takingDate',
- label: '鐩樼偣鏃ユ湡',
- component: 'DatePicker',
- componentProps: {
- format: 'YYYY-MM-DD',
- placeholder: '璇烽�夋嫨鐩樼偣鏃ユ湡',
- valueFormat: 'YYYY-MM-DD',
- },
- rules: 'required',
- },
- {
- fieldName: 'blindFlag',
- label: '鏄惁鐩茬洏',
- component: 'Switch',
- componentProps: {
- checkedChildren: '鏄�',
- unCheckedChildren: '鍚�',
- },
- rules: z.boolean().default(false),
- },
- {
- fieldName: 'frozen',
- label: '鏄惁鍐荤粨搴撳瓨',
- component: 'Switch',
- componentProps: {
- checkedChildren: '鏄�',
- unCheckedChildren: '鍚�',
- },
- rules: z.boolean().default(false),
- },
- {
- fieldName: 'userId',
- label: '鐩樼偣浜�',
- component: 'ApiSelect',
- componentProps: {
- allowClear: true,
- api: getSimpleUserList,
- labelField: 'nickname',
- placeholder: '璇烽�夋嫨鐩樼偣浜�',
- valueField: 'id',
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勬悳绱㈣〃鍗� */
-export function useGridFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'type',
- label: '鐩樼偣绫诲瀷',
- component: 'Select',
- componentProps: {
- allowClear: true,
- options: getDictOptions(DICT_TYPE.MES_WM_STOCK_TAKING_TYPE, 'number'),
- placeholder: '璇烽�夋嫨鐩樼偣绫诲瀷',
- },
- },
- {
- fieldName: 'code',
- label: '浠诲姟缂栫爜',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ヤ换鍔$紪鐮�',
- },
- },
- {
- fieldName: 'name',
- label: '浠诲姟鍚嶇О',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ヤ换鍔″悕绉�',
- },
- },
- {
- fieldName: 'takingDate',
- label: '鐩樼偣鏃ユ湡',
- component: 'RangePicker',
- componentProps: {
- ...getRangePickerDefaultProps(),
- allowClear: true,
- },
- },
- {
- fieldName: 'status',
- label: '鍗曟嵁鐘舵��',
- component: 'Select',
- componentProps: {
- allowClear: true,
- options: getDictOptions(
- DICT_TYPE.MES_WM_STOCK_TAKING_TASK_STATUS,
- 'number',
- ),
- placeholder: '璇烽�夋嫨鍗曟嵁鐘舵��',
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勫瓧娈� */
-export function useGridColumns(): VxeTableGridOptions<MesWmStockTakingTaskApi.StockTakingTask>['columns'] {
- return [
- {
- field: 'code',
- title: '浠诲姟缂栫爜',
- minWidth: 160,
- slots: { default: 'code' },
- },
- {
- field: 'name',
- title: '浠诲姟鍚嶇О',
- minWidth: 160,
- },
- {
- field: 'type',
- title: '鐩樼偣绫诲瀷',
- minWidth: 120,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_STOCK_TAKING_TYPE },
- },
- },
- {
- field: 'planName',
- title: '鐩樼偣鏂规',
- minWidth: 180,
- },
- {
- field: 'takingDate',
- title: '鐩樼偣鏃ユ湡',
- minWidth: 180,
- formatter: 'formatDate',
- },
- {
- field: 'userNickname',
- title: '鐩樼偣浜�',
- minWidth: 120,
- },
- {
- field: 'status',
- title: '鍗曟嵁鐘舵��',
- minWidth: 110,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_STOCK_TAKING_TASK_STATUS },
- },
- },
- {
- title: '鎿嶄綔',
- width: 280,
- fixed: 'right',
- slots: { default: 'actions' },
- },
- ];
-}
-
-/** 鐩樼偣浠诲姟琛屽垪琛ㄧ殑瀛楁 */
-export function useLineGridColumns(
- editable = true,
-): VxeTableGridOptions<MesWmStockTakingTaskLineApi.StockTakingTaskLine>['columns'] {
- return [
- {
- field: 'itemCode',
- title: '鐗╂枡缂栫爜',
- minWidth: 140,
- },
- {
- field: 'itemName',
- title: '鐗╂枡鍚嶇О',
- minWidth: 160,
- },
- {
- field: 'specification',
- title: '瑙勬牸鍨嬪彿',
- minWidth: 120,
- },
- {
- field: 'unitMeasureName',
- title: '鍗曚綅',
- width: 90,
- },
- {
- field: 'batchCode',
- title: '鎵规鍙�',
- minWidth: 120,
- },
- {
- field: 'quantity',
- title: '鍦ㄥ簱鏁伴噺',
- width: 120,
- },
- {
- field: 'warehouseName',
- title: '浠撳簱',
- minWidth: 120,
- },
- {
- field: 'locationName',
- title: '搴撳尯',
- minWidth: 120,
- },
- {
- field: 'areaName',
- title: '搴撲綅',
- minWidth: 120,
- },
- {
- field: 'status',
- title: '鐘舵��',
- minWidth: 100,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_STOCK_TAKING_LINE_STATUS },
- },
- },
- ...(editable
- ? [
- {
- title: '鎿嶄綔',
- width: 80,
- fixed: 'right',
- slots: { default: 'actions' },
- } as const,
- ]
- : []),
- ];
-}
-
-/** 鐩樼偣缁撴灉鍒楄〃鐨勫瓧娈� */
-export function useResultGridColumns(
- editable = true,
-): VxeTableGridOptions<MesWmStockTakingResultApi.StockTakingResult>['columns'] {
- return [
- {
- field: 'itemCode',
- title: '浜у搧鐗╂枡缂栫爜',
- minWidth: 140,
- },
- {
- field: 'itemName',
- title: '浜у搧鐗╂枡鍚嶇О',
- minWidth: 160,
- },
- {
- field: 'specification',
- title: '瑙勬牸鍨嬪彿',
- minWidth: 120,
- },
- {
- field: 'unitMeasureName',
- title: '鍗曚綅鍚嶇О',
- width: 90,
- },
- {
- field: 'warehouseName',
- title: '浠撳簱',
- minWidth: 120,
- },
- {
- field: 'locationName',
- title: '搴撳尯',
- minWidth: 120,
- },
- {
- field: 'areaName',
- title: '搴撲綅',
- minWidth: 120,
- },
- {
- field: 'quantity',
- title: '鏁伴噺',
- minWidth: 120,
- },
- {
- field: 'takingQuantity',
- title: '鐩樼偣鏁伴噺',
- minWidth: 120,
- },
- ...(editable
- ? [
- {
- title: '鎿嶄綔',
- width: 160,
- fixed: 'right',
- slots: { default: 'actions' },
- } as const,
- ]
- : []),
- ];
-}
-
-/** 鐩樼偣缁撴灉鏂板/淇敼鐨勮〃鍗� */
-export function useResultFormSchema(
- formApi?: VbenFormApi,
- taskLines: MesWmStockTakingTaskLineApi.StockTakingTaskLine[] = [],
-): VbenFormSchema[] {
- return [
- {
- fieldName: 'lineId',
- label: '鐩樼偣娓呭崟',
- component: 'Select',
- componentProps: {
- allowClear: true,
- // 閫夋嫨鐩樼偣娓呭崟鍚庯紝鑷姩甯﹀嚭鐗╂枡銆佹壒娆″拰浠撳偍浣嶇疆淇℃伅
- onChange: async (lineId?: number) => {
- const line = taskLines.find((item) => item.id === lineId);
- await formApi?.setValues({
- areaId: line?.areaId,
- batchCode: line?.batchCode,
- batchId: line?.batchId,
- itemId: line?.itemId,
- locationId: line?.locationId,
- materialStockId: line?.materialStockId,
- warehouseId: line?.warehouseId,
- });
- },
- options: taskLines.map((line) => ({
- label: `${line.itemCode} - ${line.itemName} (${line.warehouseName}${
- line.locationName ? ` / ${line.locationName}` : ''
- }${line.areaName ? ` / ${line.areaName}` : ''})`,
- value: line.id,
- })),
- placeholder: '璇烽�夋嫨鐩樼偣娓呭崟锛堝彲閫夛級',
- },
- formItemClass: 'col-span-3',
- },
- {
- fieldName: 'itemId',
- label: '鐗╂枡',
- component: markRaw(MdItemSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨鐗╂枡',
- },
- rules: 'selectRequired',
- // 閫変腑鐩樼偣娓呭崟鍚庯紝鐗╂枡鐢辨竻鍗曞甫鍑轰笖绂佹鏀瑰姩
- dependencies: {
- triggerFields: ['lineId'],
- disabled: (values) => values.lineId !== null,
- },
- },
- {
- fieldName: 'batchCode',
- label: '鎵规缂栫爜',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ユ壒娆$紪鐮�',
- },
- // 閫変腑鐩樼偣娓呭崟鍚庯紝鎵规鐢辨竻鍗曞甫鍑轰笖绂佹鏀瑰姩
- dependencies: {
- triggerFields: ['lineId'],
- disabled: (values) => values.lineId !== null,
- },
- },
- {
- fieldName: 'takingQuantity',
- label: '鐩樼偣鏁伴噺',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- placeholder: '璇疯緭鍏ョ洏鐐规暟閲�',
- precision: 2,
- },
- rules: 'required',
- },
- {
- fieldName: 'warehouseId',
- label: '浠撳簱',
- component: markRaw(WmWarehouseSelect),
- componentProps: {
- // 浠撳簱鍙樺寲鏃舵竻绌哄簱鍖哄拰搴撲綅
- onChange: () =>
- formApi?.setValues({
- areaId: undefined,
- locationId: undefined,
- }),
- placeholder: '璇烽�夋嫨浠撳簱',
- },
- rules: 'selectRequired',
- // 閫変腑鐩樼偣娓呭崟鍚庯紝浠撳簱鐢辨竻鍗曞甫鍑轰笖绂佹鏀瑰姩
- dependencies: {
- triggerFields: ['lineId'],
- disabled: (values) => values.lineId !== null,
- },
- },
- {
- fieldName: 'locationId',
- label: '搴撳尯',
- component: markRaw(WmWarehouseLocationSelect),
- rules: 'selectRequired',
- dependencies: {
- triggerFields: ['warehouseId', 'lineId'],
- show: (values) => !!values.warehouseId,
- // 閫変腑鐩樼偣娓呭崟鍚庯紝搴撳尯鐢辨竻鍗曞甫鍑轰笖绂佹鏀瑰姩
- disabled: (values) => values.lineId !== null,
- componentProps: (values) => ({
- onChange: () => formApi?.setFieldValue('areaId', undefined),
- placeholder: '璇烽�夋嫨搴撳尯',
- warehouseId: values.warehouseId,
- }),
- },
- },
- {
- fieldName: 'areaId',
- label: '搴撲綅',
- component: markRaw(WmWarehouseAreaSelect),
- rules: 'selectRequired',
- dependencies: {
- triggerFields: ['locationId', 'lineId'],
- show: (values) => !!values.locationId,
- // 閫変腑鐩樼偣娓呭崟鍚庯紝搴撲綅鐢辨竻鍗曞甫鍑轰笖绂佹鏀瑰姩
- disabled: (values) => values.lineId !== null,
- componentProps: (values) => ({
- locationId: values.locationId,
- placeholder: '璇烽�夋嫨搴撲綅',
- }),
- },
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
diff --git a/src/views/stocktaking/task/index.vue b/src/views/stocktaking/task/index.vue
deleted file mode 100644
index 4ffefe8..0000000
--- a/src/views/stocktaking/task/index.vue
+++ /dev/null
@@ -1,201 +0,0 @@
-<script lang="ts" setup>
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmStockTakingTaskApi } from '#/api/mes/wm/stocktaking/task';
-
-import { Page, useVbenModal } from '@vben/common-ui';
-import { MesWmStockTakingTaskStatusEnum } from '@vben/constants';
-import { downloadFileFromBlobPart } from '@vben/utils';
-
-import { Button, message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import {
- cancelStockTaking,
- deleteStockTaking,
- exportStockTaking,
- getStockTakingPage,
-} from '#/api/mes/wm/stocktaking/task';
-import { $t } from '#/locales';
-
-import { useGridColumns, useGridFormSchema } from './data';
-import Form from './modules/form.vue';
-
-const [FormModal, formModalApi] = useVbenModal({
- connectedComponent: Form,
- destroyOnClose: true,
-});
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- gridApi.query();
-}
-
-/** 鍒涘缓鐩樼偣浠诲姟 */
-function handleCreate() {
- formModalApi.setData({ formType: 'create' }).open();
-}
-
-/** 鏌ョ湅鐩樼偣浠诲姟 */
-function handleDetail(row: MesWmStockTakingTaskApi.StockTakingTask) {
- formModalApi.setData({ formType: 'detail', id: row.id }).open();
-}
-
-/** 缂栬緫鐩樼偣浠诲姟 */
-function handleEdit(row: MesWmStockTakingTaskApi.StockTakingTask) {
- formModalApi.setData({ formType: 'update', id: row.id }).open();
-}
-
-/** 鎻愪氦鐩樼偣浠诲姟 */
-function handleSubmit(row: MesWmStockTakingTaskApi.StockTakingTask) {
- formModalApi.setData({ formType: 'submit', id: row.id }).open();
-}
-
-/** 鎵ц鐩樼偣 */
-function handleExecute(row: MesWmStockTakingTaskApi.StockTakingTask) {
- formModalApi.setData({ formType: 'execute', id: row.id }).open();
-}
-
-/** 鍙栨秷鐩樼偣浠诲姟 */
-async function handleCancel(row: MesWmStockTakingTaskApi.StockTakingTask) {
- await cancelStockTaking(row.id!);
- message.success('鍙栨秷鎴愬姛');
- handleRefresh();
-}
-
-/** 鍒犻櫎鐩樼偣浠诲姟 */
-async function handleDelete(row: MesWmStockTakingTaskApi.StockTakingTask) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.code]),
- duration: 0,
- });
- try {
- await deleteStockTaking(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.code]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-/** 瀵煎嚭琛ㄦ牸 */
-async function handleExport() {
- const data = await exportStockTaking(await gridApi.formApi.getValues());
- downloadFileFromBlobPart({ fileName: '鐩樼偣浠诲姟.xls', source: data });
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- formOptions: {
- schema: useGridFormSchema(),
- },
- gridOptions: {
- columns: useGridColumns(),
- height: 'auto',
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }, formValues) => {
- return await getStockTakingPage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- ...formValues,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- search: true,
- },
- } as VxeTableGridOptions<MesWmStockTakingTaskApi.StockTakingTask>,
-});
-
-const StatusEnum = MesWmStockTakingTaskStatusEnum;
-</script>
-
-<template>
- <Page auto-content-height><FormModal @success="handleRefresh" />
-
- <Grid table-title="鐩樼偣浠诲姟鍒楄〃">
- <template #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: $t('ui.actionTitle.create', ['鐩樼偣浠诲姟']),
- type: 'primary',
- icon: ACTION_ICON.ADD,
- auth: ['mes:wm-stock-taking-task:create'],
- onClick: handleCreate,
- },
- {
- label: $t('ui.actionTitle.export'),
- type: 'primary',
- icon: ACTION_ICON.DOWNLOAD,
- auth: ['mes:wm-stock-taking-task:export'],
- onClick: handleExport,
- },
- ]"
- />
- </template>
- <template #code="{ row }">
- <Button type="link" @click="handleDetail(row)">
- {{ row.code }}
- </Button>
- </template>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- auth: ['mes:wm-stock-taking-task:update'],
- ifShow: row.status === StatusEnum.PREPARE,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: '鎻愪氦',
- type: 'link',
- auth: ['mes:wm-stock-taking-task:update'],
- ifShow: row.status === StatusEnum.PREPARE,
- onClick: handleSubmit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- auth: ['mes:wm-stock-taking-task:delete'],
- ifShow: row.status === StatusEnum.PREPARE,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.code]),
- confirm: handleDelete.bind(null, row),
- },
- },
- {
- label: '鎵ц鐩樼偣',
- type: 'link',
- auth: ['mes:wm-stock-taking-task:update'],
- ifShow: row.status === StatusEnum.APPROVING,
- onClick: handleExecute.bind(null, row),
- },
- {
- label: '鍙栨秷',
- type: 'link',
- danger: true,
- auth: ['mes:wm-stock-taking-task:update'],
- ifShow: row.status === StatusEnum.APPROVING,
- popConfirm: {
- title: '纭鍙栨秷璇ョ洏鐐逛换鍔★紵鍙栨秷鍚庝笉鍙仮澶嶃��',
- confirm: handleCancel.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </Page>
-</template>
diff --git a/src/views/stocktaking/task/modules/form.vue b/src/views/stocktaking/task/modules/form.vue
deleted file mode 100644
index ec1c5ba..0000000
--- a/src/views/stocktaking/task/modules/form.vue
+++ /dev/null
@@ -1,226 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { MesWmStockTakingTaskApi } from '#/api/mes/wm/stocktaking/task';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-import { MesWmStockTakingTaskStatusEnum } from '@vben/constants';
-import { useUserStore } from '@vben/stores';
-
-import { Button, message, Popconfirm, Tabs } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createStockTaking,
- finishStockTaking,
- getStockTaking,
- submitStockTaking,
- updateStockTaking,
-} from '#/api/mes/wm/stocktaking/task';
-import { $t } from '#/locales';
-
-import { useFormSchema } from '../data';
-import LineList from './line-list.vue';
-import ResultList from './result-list.vue';
-
-const emit = defineEmits(['success']);
-const userStore = useUserStore();
-const formType = ref<FormType>('create');
-const formData = ref<MesWmStockTakingTaskApi.StockTakingTask>();
-const subTabsName = ref('lines'); // 瀛愯〃褰撳墠 tab
-const originalSnapshot = ref(''); // 琛ㄥ崟鍘熷鏁版嵁蹇収锛岀敤浜庢彁浜ゆ椂璺宠繃鏈彉鏇寸殑淇濆瓨璇锋眰
-
-const isEditable = computed(() =>
- ['create', 'update'].includes(formType.value),
-);
-const isExecute = computed(() => formType.value === 'execute'); // 鏄惁鎵ц鐩樼偣妯″紡
-const isSubmit = computed(() => formType.value === 'submit'); // 鏄惁鎻愪氦妯″紡
-const canSubmit = computed(
- () =>
- formType.value === 'update' &&
- formData.value?.status === MesWmStockTakingTaskStatusEnum.PREPARE,
-);
-const showLineTab = computed(() => !formData.value?.blindFlag); // 鐩茬洏涓嶅睍绀虹洏鐐规竻鍗�
-const showResultTab = computed(
- () =>
- isExecute.value ||
- (!!formData.value?.status &&
- formData.value.status !== MesWmStockTakingTaskStatusEnum.PREPARE),
-);
-const getTitle = computed(() => {
- if (formType.value === 'detail') {
- return $t('ui.actionTitle.view', ['鐩樼偣浠诲姟']);
- }
- if (formType.value === 'execute') {
- return '鎵ц鐩樼偣';
- }
- if (formType.value === 'submit') {
- return '鎻愪氦鐩樼偣浠诲姟';
- }
- return formType.value === 'update'
- ? $t('ui.actionTitle.edit', ['鐩樼偣浠诲姟'])
- : $t('ui.actionTitle.create', ['鐩樼偣浠诲姟']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 110,
- },
- layout: 'horizontal',
- schema: [],
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-/** 鎻愪氦鐩樼偣浠诲姟锛氳〃鍗曟湁淇敼鏃跺厛淇濆瓨锛屽啀璋冪敤鎻愪氦鎺ュ彛 */
-async function handleSubmit() {
- const { valid } = await formApi.validate();
- if (!valid || !formData.value?.id) {
- return;
- }
- modalApi.lock();
- try {
- const current = JSON.stringify(await formApi.getValues());
- if (current !== originalSnapshot.value) {
- const data =
- (await formApi.getValues()) as MesWmStockTakingTaskApi.StockTakingTask;
- await updateStockTaking({ ...formData.value, ...data });
- originalSnapshot.value = current;
- }
- await submitStockTaking(formData.value.id);
- message.success('鎻愪氦鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-/** 鎵ц鐩樼偣 */
-async function handleExecute() {
- if (!formData.value?.id) {
- return;
- }
- modalApi.lock();
- try {
- await finishStockTaking(formData.value.id);
- message.success('鎵ц鐩樼偣鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- if (!isEditable.value) {
- await modalApi.close();
- return;
- }
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data =
- (await formApi.getValues()) as MesWmStockTakingTaskApi.StockTakingTask;
- try {
- if (formData.value?.id) {
- await updateStockTaking({ ...formData.value, ...data });
- formData.value = { ...formData.value, ...data };
- } else {
- const id = await createStockTaking(data);
- formData.value = {
- ...data,
- id,
- status: MesWmStockTakingTaskStatusEnum.PREPARE,
- };
- await formApi.setFieldValue('id', id);
- await formApi.setFieldValue('status', formData.value.status);
- formType.value = 'update';
- }
- originalSnapshot.value = JSON.stringify(await formApi.getValues());
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- originalSnapshot.value = '';
- return;
- }
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{ formType: FormType; id?: number }>();
- formType.value = data.formType;
- subTabsName.value = data.formType === 'execute' ? 'results' : 'lines';
- formApi.setState({ schema: useFormSchema(formType.value, formApi) });
- formApi.setDisabled(!isEditable.value);
- modalApi.setState({ showConfirmButton: isEditable.value });
- if (data?.id) {
- modalApi.lock();
- try {
- formData.value = await getStockTaking(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- } else {
- // 鏂板缓鏃堕粯璁ょ洏鐐逛汉涓哄綋鍓嶇櫥褰曠敤鎴�
- await formApi.setFieldValue('userId', userStore.userInfo?.id);
- }
- originalSnapshot.value = JSON.stringify(await formApi.getValues());
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-4/5">
- <Form class="mx-4" />
- <Tabs
- v-if="formData?.id"
- v-model:active-key="subTabsName"
- class="mx-4 mt-4"
- type="card"
- >
- <Tabs.TabPane v-if="showLineTab" key="lines" tab="鐩樼偣娓呭崟">
- <LineList :form-type="formType" :task-id="formData.id" />
- </Tabs.TabPane>
- <Tabs.TabPane v-if="showResultTab" key="results" tab="鐩樼偣缁撴灉">
- <ResultList
- :form-type="isExecute ? 'execute' : 'detail'"
- :task-id="formData.id"
- />
- </Tabs.TabPane>
- </Tabs>
- <template #prepend-footer>
- <div class="flex flex-auto items-center gap-2">
- <Popconfirm
- v-if="canSubmit || isSubmit"
- title="纭鎻愪氦璇ョ洏鐐逛换鍔★紵銆愭彁浜ゅ悗灏嗕笉鑳戒慨鏀广��"
- @confirm="handleSubmit"
- >
- <Button type="primary">鎻愪氦</Button>
- </Popconfirm>
- <Popconfirm
- v-if="isExecute"
- title="纭鎵ц鐩樼偣鎿嶄綔锛�"
- @confirm="handleExecute"
- >
- <Button type="primary">鎵ц鐩樼偣</Button>
- </Popconfirm>
- </div>
- </template>
- </Modal>
-</template>
diff --git a/src/views/stocktaking/task/modules/line-list.vue b/src/views/stocktaking/task/modules/line-list.vue
deleted file mode 100644
index ee1eee7..0000000
--- a/src/views/stocktaking/task/modules/line-list.vue
+++ /dev/null
@@ -1,151 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmMaterialStockApi } from '#/api/mes/wm/materialstock';
-import type { MesWmStockTakingTaskLineApi } from '#/api/mes/wm/stocktaking/task/line';
-
-import { computed, ref } from 'vue';
-
-import { message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import {
- createStockTakingTaskLine,
- deleteStockTakingTaskLine,
- getStockTakingTaskLinePage,
-} from '#/api/mes/wm/stocktaking/task/line';
-import { $t } from '#/locales';
-import { WmMaterialStockSelectDialog } from '#/views/wls/materialstock/components';
-
-import { useLineGridColumns } from '../data';
-
-const props = defineProps<{
- formType: FormType;
- taskId: number;
-}>();
-
-const isEditable = computed(() => props.formType === 'update'); // 浠呯紪杈戞�佸彲缁存姢鐩樼偣娓呭崟
-const dialogRef = ref<InstanceType<typeof WmMaterialStockSelectDialog>>();
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- gridApi.query();
-}
-
-/** 鎵撳紑搴撳瓨閫夋嫨寮圭獥鎵归噺娣诲姞鐗╂枡 */
-function handleAdd() {
- dialogRef.value?.open([], { multiple: true });
-}
-
-/** 搴撳瓨閫夋嫨纭鍥炶皟锛氬皢閫変腑鐨勫簱瀛樿褰曟壒閲忓垱寤轰负鐩樼偣琛� */
-async function handleStockSelected(
- rows: MesWmMaterialStockApi.MaterialStock[],
-) {
- if (rows.length === 0) {
- return;
- }
- for (const stock of rows) {
- await createStockTakingTaskLine({
- areaId: stock.areaId,
- batchId: stock.batchId,
- itemId: stock.itemId,
- locationId: stock.locationId,
- materialStockId: stock.id,
- quantity: stock.quantity,
- taskId: props.taskId,
- warehouseId: stock.warehouseId,
- });
- }
- message.success(`鎴愬姛娣诲姞 ${rows.length} 鏉$洏鐐硅`);
- handleRefresh();
-}
-
-/** 鍒犻櫎鐩樼偣琛� */
-async function handleDelete(
- row: MesWmStockTakingTaskLineApi.StockTakingTaskLine,
-) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.itemName]),
- duration: 0,
- });
- try {
- await deleteStockTakingTaskLine(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.itemName]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- gridOptions: {
- columns: useLineGridColumns(isEditable.value),
- height: 360,
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }) => {
- if (!props.taskId) {
- return { list: [], total: 0 };
- }
- return await getStockTakingTaskLinePage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- taskId: props.taskId,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- },
- } as VxeTableGridOptions<MesWmStockTakingTaskLineApi.StockTakingTaskLine>,
-});
-
-defineExpose({ refresh: handleRefresh });
-</script>
-
-<template>
- <div>
- <WmMaterialStockSelectDialog
- ref="dialogRef"
- @selected="handleStockSelected"
- />
- <Grid table-title="鐩樼偣娓呭崟">
- <template v-if="isEditable" #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: '娣诲姞鐗╂枡',
- type: 'primary',
- icon: ACTION_ICON.ADD,
- auth: ['mes:wm-stock-taking-task:update'],
- onClick: handleAdd,
- },
- ]"
- />
- </template>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.itemName]),
- confirm: handleDelete.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </div>
-</template>
diff --git a/src/views/stocktaking/task/modules/result-form.vue b/src/views/stocktaking/task/modules/result-form.vue
deleted file mode 100644
index 9d21b67..0000000
--- a/src/views/stocktaking/task/modules/result-form.vue
+++ /dev/null
@@ -1,106 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmStockTakingResultApi } from '#/api/mes/wm/stocktaking/task/result';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import { getStockTakingTaskLineSimpleList } from '#/api/mes/wm/stocktaking/task/line';
-import {
- createStockTakingResult,
- getStockTakingResult,
- updateStockTakingResult,
-} from '#/api/mes/wm/stocktaking/task/result';
-import { $t } from '#/locales';
-
-import { useResultFormSchema } from '../data';
-
-const emit = defineEmits(['success']);
-const formData = ref<MesWmStockTakingResultApi.StockTakingResult>();
-const taskId = ref<number>(); // 鎵�灞炵洏鐐逛换鍔$紪鍙�
-const isExecute = ref(false); // 鏄惁鎵ц鐩樼偣妯″紡锛堝彲閫夋嫨鐩樼偣娓呭崟鍥炲~锛�
-const getTitle = computed(() =>
- formData.value?.id
- ? $t('ui.actionTitle.edit', ['鐩樼偣缁撴灉'])
- : $t('ui.actionTitle.create', ['鐩樼偣缁撴灉']),
-);
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 100,
- },
- layout: 'horizontal',
- schema: [],
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data =
- (await formApi.getValues()) as MesWmStockTakingResultApi.StockTakingResult;
- data.taskId = taskId.value;
- try {
- await (formData.value?.id
- ? updateStockTakingResult({ ...data, id: formData.value.id })
- : createStockTakingResult(data));
- // 鍏抽棴骞舵彁绀�
- await modalApi.close();
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- return;
- }
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{
- execute?: boolean;
- id?: number;
- taskId: number;
- }>();
- taskId.value = data.taskId;
- isExecute.value = !!data.execute;
- // 鎵ц鐩樼偣妯″紡锛氬姞杞界洏鐐规竻鍗曚綔涓哄彲閫夐」锛屼緵閫夋嫨鍚庡洖濉�
- const taskLines =
- isExecute.value && !data.id
- ? await getStockTakingTaskLineSimpleList(data.taskId)
- : [];
- formApi.setState({ schema: useResultFormSchema(formApi, taskLines) });
- if (!data.id) {
- return;
- }
- modalApi.lock();
- try {
- formData.value = await getStockTakingResult(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form />
- </Modal>
-</template>
diff --git a/src/views/stocktaking/task/modules/result-list.vue b/src/views/stocktaking/task/modules/result-list.vue
deleted file mode 100644
index 0e9c315..0000000
--- a/src/views/stocktaking/task/modules/result-list.vue
+++ /dev/null
@@ -1,136 +0,0 @@
-<script lang="ts" setup>
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmStockTakingResultApi } from '#/api/mes/wm/stocktaking/task/result';
-
-import { computed } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import {
- deleteStockTakingResult,
- getStockTakingResultPage,
-} from '#/api/mes/wm/stocktaking/task/result';
-import { $t } from '#/locales';
-
-import { useResultGridColumns } from '../data';
-import ResultForm from './result-form.vue';
-
-const props = defineProps<{
- formType: 'detail' | 'execute';
- taskId: number;
-}>();
-
-const isExecute = computed(() => props.formType === 'execute'); // 鎵ц鐩樼偣鎬佸彲缁存姢鐩樼偣缁撴灉
-
-const [ResultFormModal, resultFormModalApi] = useVbenModal({
- connectedComponent: ResultForm,
- destroyOnClose: true,
-});
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- gridApi.query();
-}
-
-/** 鏂板鐩樼偣缁撴灉 */
-function handleCreate() {
- resultFormModalApi.setData({ execute: true, taskId: props.taskId }).open();
-}
-
-/** 缂栬緫鐩樼偣缁撴灉 */
-function handleEdit(row: MesWmStockTakingResultApi.StockTakingResult) {
- resultFormModalApi.setData({ id: row.id, taskId: props.taskId }).open();
-}
-
-/** 鍒犻櫎鐩樼偣缁撴灉 */
-async function handleDelete(row: MesWmStockTakingResultApi.StockTakingResult) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.itemName]),
- duration: 0,
- });
- try {
- await deleteStockTakingResult(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.itemName]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- gridOptions: {
- columns: useResultGridColumns(isExecute.value),
- height: 360,
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }) => {
- if (!props.taskId) {
- return { list: [], total: 0 };
- }
- return await getStockTakingResultPage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- taskId: props.taskId,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- },
- } as VxeTableGridOptions<MesWmStockTakingResultApi.StockTakingResult>,
-});
-
-defineExpose({ refresh: handleRefresh });
-</script>
-
-<template>
- <div>
- <ResultFormModal @success="handleRefresh" />
- <Grid table-title="鐩樼偣缁撴灉">
- <template v-if="isExecute" #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: $t('common.create'),
- type: 'primary',
- icon: ACTION_ICON.ADD,
- auth: ['mes:wm-stock-taking-task:update'],
- onClick: handleCreate,
- },
- ]"
- />
- </template>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.itemName]),
- confirm: handleDelete.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </div>
-</template>
diff --git a/src/views/transfer/data.ts b/src/views/transfer/data.ts
deleted file mode 100644
index 461044c..0000000
--- a/src/views/transfer/data.ts
+++ /dev/null
@@ -1,647 +0,0 @@
-import type { VbenFormApi, VbenFormSchema } from '#/adapter/form';
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmMaterialStockApi } from '#/api/mes/wm/materialstock';
-import type { MesWmTransferApi } from '#/api/mes/wm/transfer';
-import type { MesWmTransferDetailApi } from '#/api/mes/wm/transfer/detail';
-import type { MesWmTransferLineApi } from '#/api/mes/wm/transfer/line';
-
-import { h, markRaw } from 'vue';
-
-import {
- DICT_TYPE,
- MesAutoCodeRuleCode,
- MesWmTransferTypeEnum,
-} from '@vben/constants';
-import { getDictOptions } from '@vben/hooks';
-
-import { Button } from 'ant-design-vue';
-
-import { z } from '#/adapter/form';
-import { generateAutoCode } from '#/api/mes/md/autocode/record';
-import { MdItemSelect } from '#/views/mes/md/item/components';
-import { WmMaterialStockSelect } from '#/views/wls/materialstock/components';
-import {
- WmWarehouseAreaSelect,
- WmWarehouseLocationSelect,
- WmWarehouseSelect,
-} from '#/views/wls/warehouse/components';
-
-/** 琛ㄥ崟绫诲瀷 */
-export type FormType =
- | 'confirm'
- | 'create'
- | 'detail'
- | 'finish'
- | 'stock'
- | 'update';
-
-/** 琛ㄥご鏄惁鍙锛堜笂鏋躲�佺‘璁ゃ�佹墽琛屻�佽鎯呮�侊級 */
-function isHeaderReadonly(formType: FormType): boolean {
- return ['confirm', 'detail', 'finish', 'stock'].includes(formType);
-}
-
-/** 鏂板/淇敼鐨勮〃鍗� */
-export function useFormSchema(
- formType: FormType,
- formApi?: VbenFormApi,
-): VbenFormSchema[] {
- const headerReadonly = isHeaderReadonly(formType);
- return [
- {
- fieldName: 'id',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'status',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'code',
- label: '杞Щ鍗曠紪鍙�',
- component: 'Input',
- componentProps: {
- disabled: headerReadonly,
- placeholder: '璇疯緭鍏ヨ浆绉诲崟缂栧彿',
- },
- rules: 'required',
- suffix:
- formType === 'create' || formType === 'update'
- ? () =>
- h(
- Button,
- {
- type: 'default',
- onClick: async () => {
- const code = await generateAutoCode(
- MesAutoCodeRuleCode.TRANSFER_CODE,
- );
- await formApi?.setFieldValue('code', code);
- },
- },
- { default: () => '鐢熸垚' },
- )
- : undefined,
- },
- {
- fieldName: 'name',
- label: '杞Щ鍗曞悕绉�',
- component: 'Input',
- componentProps: {
- disabled: headerReadonly,
- placeholder: '璇疯緭鍏ヨ浆绉诲崟鍚嶇О',
- },
- rules: 'required',
- },
- {
- fieldName: 'type',
- label: '杞Щ鍗曠被鍨�',
- component: 'Select',
- componentProps: {
- disabled: headerReadonly,
- options: getDictOptions(DICT_TYPE.MES_WM_TRANSFER_TYPE, 'number'),
- placeholder: '璇烽�夋嫨杞Щ鍗曠被鍨�',
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'transferDate',
- label: '杞Щ鏃ユ湡',
- component: 'DatePicker',
- componentProps: {
- class: '!w-full',
- disabled: headerReadonly,
- format: 'YYYY-MM-DD',
- placeholder: '璇烽�夋嫨杞Щ鏃ユ湡',
- valueFormat: 'YYYY-MM-DD 00:00:00',
- },
- rules: 'required',
- },
- {
- fieldName: 'deliveryFlag',
- label: '鏄惁閰嶉��',
- component: 'Switch',
- componentProps: {
- disabled: headerReadonly,
- },
- rules: z.boolean().default(false),
- dependencies: {
- triggerFields: ['type'],
- show: (values) => values.type === MesWmTransferTypeEnum.OUTER,
- },
- },
- {
- fieldName: 'confirmFlag',
- label: '鏄惁纭',
- component: 'Switch',
- componentProps: {
- disabled: true,
- },
- dependencies: {
- triggerFields: ['type'],
- show: (values) => values.type === MesWmTransferTypeEnum.OUTER,
- },
- },
- {
- fieldName: 'recipientName',
- label: '鏀惰揣浜�',
- component: 'Input',
- componentProps: {
- disabled: headerReadonly,
- placeholder: '璇疯緭鍏ユ敹璐т汉',
- },
- dependencies: {
- triggerFields: ['type', 'deliveryFlag'],
- show: (values) =>
- values.type === MesWmTransferTypeEnum.OUTER && !!values.deliveryFlag,
- },
- },
- {
- fieldName: 'recipientTelephone',
- label: '鑱旂郴鐢佃瘽',
- component: 'Input',
- componentProps: {
- disabled: headerReadonly,
- placeholder: '璇疯緭鍏ヨ仈绯荤數璇�',
- },
- dependencies: {
- triggerFields: ['type', 'deliveryFlag'],
- show: (values) =>
- values.type === MesWmTransferTypeEnum.OUTER && !!values.deliveryFlag,
- },
- },
- {
- fieldName: 'carrier',
- label: '鎵胯繍鍟�',
- component: 'Input',
- componentProps: {
- disabled: headerReadonly,
- placeholder: '璇疯緭鍏ユ壙杩愬晢',
- },
- dependencies: {
- triggerFields: ['type', 'deliveryFlag'],
- show: (values) =>
- values.type === MesWmTransferTypeEnum.OUTER && !!values.deliveryFlag,
- },
- },
- {
- fieldName: 'shippingNumber',
- label: '杩愯緭鍗曞彿',
- component: 'Input',
- componentProps: {
- disabled: headerReadonly,
- placeholder: '璇疯緭鍏ヨ繍杈撳崟鍙�',
- },
- dependencies: {
- triggerFields: ['type', 'deliveryFlag'],
- show: (values) =>
- values.type === MesWmTransferTypeEnum.OUTER && !!values.deliveryFlag,
- },
- },
- {
- fieldName: 'destinationAddress',
- label: '鐩殑鍦�',
- component: 'Input',
- formItemClass: 'col-span-2',
- componentProps: {
- disabled: headerReadonly,
- placeholder: '璇疯緭鍏ョ洰鐨勫湴',
- },
- dependencies: {
- triggerFields: ['type', 'deliveryFlag'],
- show: (values) =>
- values.type === MesWmTransferTypeEnum.OUTER && !!values.deliveryFlag,
- },
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- disabled: headerReadonly,
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勬悳绱㈣〃鍗� */
-export function useGridFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'code',
- label: '杞Щ鍗曠紪鍙�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ヨ浆绉诲崟缂栧彿',
- },
- },
- {
- fieldName: 'name',
- label: '杞Щ鍗曞悕绉�',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ヨ浆绉诲崟鍚嶇О',
- },
- },
- {
- fieldName: 'type',
- label: '杞Щ鍗曠被鍨�',
- component: 'Select',
- componentProps: {
- allowClear: true,
- options: getDictOptions(DICT_TYPE.MES_WM_TRANSFER_TYPE, 'number'),
- placeholder: '璇烽�夋嫨杞Щ鍗曠被鍨�',
- },
- },
- {
- fieldName: 'status',
- label: '鍗曟嵁鐘舵��',
- component: 'Select',
- componentProps: {
- allowClear: true,
- options: getDictOptions(DICT_TYPE.MES_WM_TRANSFER_STATUS, 'number'),
- placeholder: '璇烽�夋嫨鍗曟嵁鐘舵��',
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勫瓧娈� */
-export function useGridColumns(): VxeTableGridOptions<MesWmTransferApi.Transfer>['columns'] {
- return [
- {
- field: 'code',
- title: '杞Щ鍗曠紪鍙�',
- minWidth: 160,
- slots: { default: 'code' },
- },
- {
- field: 'name',
- title: '杞Щ鍗曞悕绉�',
- minWidth: 160,
- },
- {
- field: 'type',
- title: '杞Щ鍗曠被鍨�',
- minWidth: 100,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_TRANSFER_TYPE },
- },
- },
- {
- field: 'deliveryFlag',
- title: '鏄惁閰嶉��',
- width: 100,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.INFRA_BOOLEAN_STRING },
- },
- },
- {
- field: 'transferDate',
- title: '杞Щ鏃ユ湡',
- width: 180,
- formatter: 'formatDate',
- },
- {
- field: 'status',
- title: '鍗曟嵁鐘舵��',
- minWidth: 110,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.MES_WM_TRANSFER_STATUS },
- },
- },
- {
- title: '鎿嶄綔',
- width: 240,
- fixed: 'right',
- slots: { default: 'actions' },
- },
- ];
-}
-
-/** 杞Щ鍗曡瀛愯〃鐨勫瓧娈� */
-export function useLineGridColumns(
- editable: boolean,
- stockable: boolean,
-): VxeTableGridOptions<MesWmTransferLineApi.TransferLine>['columns'] {
- return [
- {
- type: 'expand',
- width: 48,
- slots: { content: 'detail' },
- },
- {
- field: 'itemCode',
- title: '鐗╂枡缂栫爜',
- minWidth: 120,
- },
- {
- field: 'itemName',
- title: '鐗╂枡鍚嶇О',
- minWidth: 140,
- },
- {
- field: 'specification',
- title: '瑙勬牸鍨嬪彿',
- minWidth: 120,
- },
- {
- field: 'unitMeasureName',
- title: '鍗曚綅',
- width: 80,
- },
- {
- field: 'quantity',
- title: '杞Щ鏁伴噺',
- width: 100,
- },
- {
- field: 'batchCode',
- title: '鎵规鍙�',
- minWidth: 120,
- },
- {
- field: 'fromWarehouseName',
- title: '绉诲嚭浠撳簱',
- minWidth: 120,
- },
- {
- field: 'fromLocationName',
- title: '绉诲嚭搴撳尯',
- minWidth: 120,
- },
- {
- field: 'fromAreaName',
- title: '绉诲嚭搴撲綅',
- minWidth: 120,
- },
- ...(editable || stockable
- ? [
- {
- title: '鎿嶄綔',
- width: 180,
- fixed: 'right',
- slots: { default: 'actions' },
- } as const,
- ]
- : []),
- ];
-}
-
-/** 杞Щ鍗曡鏂板/淇敼鐨勮〃鍗� */
-export function useLineFormSchema(formApi?: VbenFormApi): VbenFormSchema[] {
- return [
- {
- fieldName: 'quantityMax',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'batchId',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'materialStockId',
- label: '閫夋嫨搴撳瓨',
- component: markRaw(WmMaterialStockSelect),
- componentProps: {
- // 閫夋嫨搴撳瓨鍚庯紝鑷姩鍥炲~鐗╂枡/浠撳簱浣嶇疆/鎵规/鏁伴噺
- onChange: async (stock?: MesWmMaterialStockApi.MaterialStock) => {
- await formApi?.setValues({
- batchCode: stock?.batchCode,
- batchId: stock?.batchId,
- fromAreaId: stock?.areaId,
- fromLocationId: stock?.locationId,
- fromWarehouseId: stock?.warehouseId,
- itemId: stock?.itemId,
- quantity: stock?.quantity,
- quantityMax: stock?.quantity,
- });
- },
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'itemId',
- label: '鐗╂枡',
- component: markRaw(MdItemSelect),
- componentProps: {
- disabled: true,
- },
- },
- {
- fieldName: 'quantity',
- label: '杞Щ鏁伴噺',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0,
- placeholder: '璇疯緭鍏ヨ浆绉绘暟閲�',
- precision: 2,
- },
- rules: 'required',
- dependencies: {
- triggerFields: ['quantityMax'],
- componentProps: (values) => ({
- class: '!w-full',
- max: values.quantityMax,
- min: 0,
- placeholder: '璇疯緭鍏ヨ浆绉绘暟閲�',
- precision: 2,
- }),
- },
- },
- {
- fieldName: 'batchCode',
- label: '鎵规鍙�',
- component: 'Input',
- componentProps: {
- disabled: true,
- },
- },
- {
- fieldName: 'fromWarehouseId',
- label: '绉诲嚭浠撳簱',
- component: markRaw(WmWarehouseSelect),
- componentProps: {
- disabled: true,
- },
- },
- {
- fieldName: 'fromLocationId',
- label: '绉诲嚭搴撳尯',
- component: markRaw(WmWarehouseLocationSelect),
- componentProps: {
- disabled: true,
- },
- dependencies: {
- triggerFields: ['fromWarehouseId'],
- componentProps: (values) => ({
- disabled: true,
- warehouseId: values.fromWarehouseId,
- }),
- },
- },
- {
- fieldName: 'fromAreaId',
- label: '绉诲嚭搴撲綅',
- component: markRaw(WmWarehouseAreaSelect),
- componentProps: {
- disabled: true,
- },
- dependencies: {
- triggerFields: ['fromLocationId'],
- componentProps: (values) => ({
- disabled: true,
- locationId: values.fromLocationId,
- }),
- },
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
-
-/** 璋冩嫧鏄庣粏瀛愯〃鐨勫瓧娈� */
-export function useDetailGridColumns(
- stockable: boolean,
-): VxeTableGridOptions<MesWmTransferDetailApi.TransferDetail>['columns'] {
- return [
- {
- field: 'toWarehouseName',
- title: '绉诲叆浠撳簱',
- minWidth: 100,
- },
- {
- field: 'toLocationName',
- title: '绉诲叆搴撳尯',
- minWidth: 100,
- },
- {
- field: 'toAreaName',
- title: '绉诲叆搴撲綅',
- minWidth: 100,
- },
- {
- field: 'quantity',
- title: '鏁伴噺',
- width: 100,
- },
- ...(stockable
- ? [
- {
- title: '鎿嶄綔',
- width: 120,
- fixed: 'right',
- slots: { default: 'actions' },
- } as const,
- ]
- : []),
- ];
-}
-
-/** 璋冩嫧鏄庣粏鏂板/淇敼鐨勮〃鍗� */
-export function useDetailFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'itemId',
- label: '鐗╂枡',
- component: markRaw(MdItemSelect),
- componentProps: {
- disabled: true,
- },
- },
- {
- fieldName: 'toWarehouseId',
- label: '绉诲叆浠撳簱',
- component: markRaw(WmWarehouseSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨绉诲叆浠撳簱',
- },
- rules: 'selectRequired',
- },
- {
- fieldName: 'toLocationId',
- label: '绉诲叆搴撳尯',
- component: markRaw(WmWarehouseLocationSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨绉诲叆搴撳尯',
- },
- rules: 'selectRequired',
- dependencies: {
- triggerFields: ['toWarehouseId'],
- componentProps: (values) => ({
- placeholder: '璇烽�夋嫨绉诲叆搴撳尯',
- warehouseId: values.toWarehouseId,
- }),
- },
- },
- {
- fieldName: 'toAreaId',
- label: '绉诲叆搴撲綅',
- component: markRaw(WmWarehouseAreaSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨绉诲叆搴撲綅',
- },
- rules: 'selectRequired',
- dependencies: {
- triggerFields: ['toLocationId'],
- componentProps: (values) => ({
- locationId: values.toLocationId,
- placeholder: '璇烽�夋嫨绉诲叆搴撲綅',
- }),
- },
- },
- {
- fieldName: 'quantity',
- label: '鏁伴噺',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0,
- placeholder: '璇疯緭鍏ユ暟閲�',
- precision: 2,
- },
- rules: 'required',
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
diff --git a/src/views/transfer/index.vue b/src/views/transfer/index.vue
deleted file mode 100644
index e027788..0000000
--- a/src/views/transfer/index.vue
+++ /dev/null
@@ -1,214 +0,0 @@
-<script lang="ts" setup>
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmTransferApi } from '#/api/mes/wm/transfer';
-
-import { Page, useVbenModal } from '@vben/common-ui';
-import { MesWmTransferStatusEnum } from '@vben/constants';
-import { downloadFileFromBlobPart } from '@vben/utils';
-
-import { Button, message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import {
- cancelTransfer,
- deleteTransfer,
- exportTransfer,
- getTransferPage,
-} from '#/api/mes/wm/transfer';
-import { $t } from '#/locales';
-
-import { useGridColumns, useGridFormSchema } from './data';
-import Form from './modules/form.vue';
-
-const [FormModal, formModalApi] = useVbenModal({
- connectedComponent: Form,
- destroyOnClose: true,
-});
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- gridApi.query();
-}
-
-/** 鍒涘缓杞Щ鍗� */
-function handleCreate() {
- formModalApi.setData({ formType: 'create' }).open();
-}
-
-/** 鏌ョ湅杞Щ鍗曡鎯� */
-function handleDetail(row: MesWmTransferApi.Transfer) {
- formModalApi.setData({ formType: 'detail', id: row.id }).open();
-}
-
-/** 缂栬緫杞Щ鍗� */
-function handleEdit(row: MesWmTransferApi.Transfer) {
- formModalApi.setData({ formType: 'update', id: row.id }).open();
-}
-
-/** 鍒拌揣纭 */
-function handleConfirm(row: MesWmTransferApi.Transfer) {
- formModalApi.setData({ formType: 'confirm', id: row.id }).open();
-}
-
-/** 鎵ц涓婃灦 */
-function handleStock(row: MesWmTransferApi.Transfer) {
- formModalApi.setData({ formType: 'stock', id: row.id }).open();
-}
-
-/** 鎵ц杞Щ */
-function handleFinish(row: MesWmTransferApi.Transfer) {
- formModalApi.setData({ formType: 'finish', id: row.id }).open();
-}
-
-/** 鍒犻櫎杞Щ鍗� */
-async function handleDelete(row: MesWmTransferApi.Transfer) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.code]),
- duration: 0,
- });
- try {
- await deleteTransfer(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.code]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-/** 鍙栨秷杞Щ鍗� */
-async function handleCancel(row: MesWmTransferApi.Transfer) {
- await cancelTransfer(row.id!);
- message.success('鍙栨秷鎴愬姛');
- handleRefresh();
-}
-
-/** 瀵煎嚭琛ㄦ牸 */
-async function handleExport() {
- const data = await exportTransfer(await gridApi.formApi.getValues());
- downloadFileFromBlobPart({ fileName: '杞Щ鍗�.xls', source: data });
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- formOptions: {
- schema: useGridFormSchema(),
- },
- gridOptions: {
- columns: useGridColumns(),
- height: 'auto',
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }, formValues) => {
- return await getTransferPage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- ...formValues,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- search: true,
- },
- } as VxeTableGridOptions<MesWmTransferApi.Transfer>,
-});
-</script>
-
-<template>
- <Page auto-content-height><FormModal @success="handleRefresh" />
-
- <Grid table-title="杞Щ鍗曞垪琛�">
- <template #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: $t('ui.actionTitle.create', ['杞Щ鍗�']),
- type: 'primary',
- icon: ACTION_ICON.ADD,
- auth: ['mes:wm-transfer:create'],
- onClick: handleCreate,
- },
- {
- label: $t('ui.actionTitle.export'),
- type: 'primary',
- icon: ACTION_ICON.DOWNLOAD,
- auth: ['mes:wm-transfer:export'],
- onClick: handleExport,
- },
- ]"
- />
- </template>
- <template #code="{ row }">
- <Button type="link" @click="handleDetail(row)">
- {{ row.code }}
- </Button>
- </template>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- auth: ['mes:wm-transfer:update'],
- ifShow: row.status === MesWmTransferStatusEnum.PREPARE,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- auth: ['mes:wm-transfer:delete'],
- ifShow: row.status === MesWmTransferStatusEnum.PREPARE,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.code]),
- confirm: handleDelete.bind(null, row),
- },
- },
- {
- label: '鍒拌揣纭',
- type: 'link',
- auth: ['mes:wm-transfer:update'],
- ifShow: row.status === MesWmTransferStatusEnum.UNCONFIRMED,
- onClick: handleConfirm.bind(null, row),
- },
- {
- label: '鎵ц涓婃灦',
- type: 'link',
- auth: ['mes:wm-transfer:update'],
- ifShow: row.status === MesWmTransferStatusEnum.APPROVING,
- onClick: handleStock.bind(null, row),
- },
- {
- label: '鎵ц杞Щ',
- type: 'link',
- auth: ['mes:wm-transfer:finish'],
- ifShow: row.status === MesWmTransferStatusEnum.APPROVED,
- onClick: handleFinish.bind(null, row),
- },
- {
- label: '鍙栨秷',
- type: 'link',
- danger: true,
- auth: ['mes:wm-transfer:update'],
- ifShow:
- row.status === MesWmTransferStatusEnum.UNCONFIRMED ||
- row.status === MesWmTransferStatusEnum.APPROVING ||
- row.status === MesWmTransferStatusEnum.APPROVED,
- popConfirm: {
- title: '纭鍙栨秷璇ヨ浆绉诲崟锛熷彇娑堝悗涓嶅彲鎭㈠銆�',
- confirm: handleCancel.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </Page>
-</template>
diff --git a/src/views/transfer/modules/detail-form.vue b/src/views/transfer/modules/detail-form.vue
deleted file mode 100644
index f83f539..0000000
--- a/src/views/transfer/modules/detail-form.vue
+++ /dev/null
@@ -1,103 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmTransferDetailApi } from '#/api/mes/wm/transfer/detail';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createTransferDetail,
- getTransferDetail,
- updateTransferDetail,
-} from '#/api/mes/wm/transfer/detail';
-import { $t } from '#/locales';
-
-import { useDetailFormSchema } from '../data';
-
-const emit = defineEmits<{ success: [lineId: number] }>();
-const formData = ref<MesWmTransferDetailApi.TransferDetail>();
-const transferId = ref<number>(); // 鎵�灞炶浆绉诲崟缂栧彿
-const lineId = ref<number>(); // 鎵�灞炶浆绉诲崟琛岀紪鍙�
-
-const getTitle = computed(() => {
- return formData.value?.id
- ? $t('ui.actionTitle.edit', ['璋冩嫧鏄庣粏'])
- : $t('ui.actionTitle.create', ['璋冩嫧鏄庣粏']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-2',
- labelWidth: 90,
- },
- layout: 'horizontal',
- schema: useDetailFormSchema(),
- showDefaultActions: false,
- wrapperClass: 'grid-cols-2',
-});
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data =
- (await formApi.getValues()) as MesWmTransferDetailApi.TransferDetail;
- data.transferId = transferId.value;
- data.lineId = lineId.value;
- try {
- await (formData.value?.id
- ? updateTransferDetail({ ...data, id: formData.value.id })
- : createTransferDetail(data));
- // 鍏抽棴骞舵彁绀�
- await modalApi.close();
- emit('success', lineId.value!);
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- return;
- }
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{
- detailId?: number;
- itemId?: number;
- lineId: number;
- transferId: number;
- }>();
- transferId.value = data.transferId;
- lineId.value = data.lineId;
- if (data.detailId) {
- modalApi.lock();
- try {
- formData.value = await getTransferDetail(data.detailId);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- } else if (data.itemId) {
- await formApi.setFieldValue('itemId', data.itemId);
- }
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-2/5">
- <Form class="mx-4" />
- </Modal>
-</template>
diff --git a/src/views/transfer/modules/detail-list.vue b/src/views/transfer/modules/detail-list.vue
deleted file mode 100644
index 4834cae..0000000
--- a/src/views/transfer/modules/detail-list.vue
+++ /dev/null
@@ -1,105 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmTransferDetailApi } from '#/api/mes/wm/transfer/detail';
-
-import { computed, watch } from 'vue';
-
-import { message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import { deleteTransferDetail } from '#/api/mes/wm/transfer/detail';
-import { $t } from '#/locales';
-
-import { useDetailGridColumns } from '../data';
-
-const props = defineProps<{
- details: MesWmTransferDetailApi.TransferDetail[];
- formType: FormType;
-}>();
-
-const emit = defineEmits<{
- edit: [detailId: number];
- refresh: [];
-}>();
-
-const isStock = computed(() => props.formType === 'stock'); // 鏄惁涓轰笂鏋舵ā寮�
-
-/** 缂栬緫璋冩嫧鏄庣粏 */
-function handleEdit(row: MesWmTransferDetailApi.TransferDetail) {
- emit('edit', row.id!);
-}
-
-/** 鍒犻櫎璋冩嫧鏄庣粏 */
-async function handleDelete(row: MesWmTransferDetailApi.TransferDetail) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.toWarehouseName]),
- duration: 0,
- });
- try {
- await deleteTransferDetail(row.id!);
- message.success(
- $t('ui.actionMessage.deleteSuccess', [row.toWarehouseName]),
- );
- emit('refresh');
- } finally {
- hideLoading();
- }
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- gridOptions: {
- border: true,
- columns: useDetailGridColumns(isStock.value),
- data: props.details,
- pagerConfig: {
- enabled: false,
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- size: 'small',
- toolbarConfig: {
- enabled: false,
- },
- } as VxeTableGridOptions<MesWmTransferDetailApi.TransferDetail>,
-});
-
-watch(
- () => props.details,
- (details) => gridApi.setGridOptions({ data: details }),
-);
-</script>
-
-<template>
- <div class="px-4 py-2">
- <Grid>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [
- row.toWarehouseName,
- ]),
- confirm: handleDelete.bind(null, row),
- },
- },
- ]"
- />
- </template>
- </Grid>
- </div>
-</template>
diff --git a/src/views/transfer/modules/form.vue b/src/views/transfer/modules/form.vue
deleted file mode 100644
index adf6732..0000000
--- a/src/views/transfer/modules/form.vue
+++ /dev/null
@@ -1,258 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { MesWmTransferApi } from '#/api/mes/wm/transfer';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-import { MesWmTransferStatusEnum } from '@vben/constants';
-
-import { Button, Divider, message, Popconfirm } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- confirmTransfer,
- createTransfer,
- finishTransfer,
- getTransfer,
- stockTransfer,
- submitTransfer,
- updateTransfer,
-} from '#/api/mes/wm/transfer';
-import { $t } from '#/locales';
-
-import { useFormSchema } from '../data';
-import LineList from './line-list.vue';
-
-const emit = defineEmits(['success']);
-const formType = ref<FormType>('create');
-const formData = ref<MesWmTransferApi.Transfer>();
-const originalSnapshot = ref(''); // 琛ㄥ崟鍘熷鏁版嵁蹇収锛岀敤浜庢彁浜ゆ椂璺宠繃鏈彉鏇寸殑淇濆瓨璇锋眰
-const isEditable = computed(() =>
- // 鏄惁涓虹紪杈戞ā寮忥紙鍙繚瀛橈級
- ['create', 'update'].includes(formType.value),
-);
-const isConfirm = computed(() => formType.value === 'confirm'); // 鏄惁涓哄埌璐х‘璁ゆā寮�
-const isStock = computed(() => formType.value === 'stock'); // 鏄惁涓轰笂鏋舵ā寮�
-const isFinish = computed(() => formType.value === 'finish'); // 鏄惁涓烘墽琛岃浆绉绘ā寮�
-const canSubmit = computed(
- () =>
- // 缂栬緫鎬佽崏绋垮彲鎻愪氦
- formType.value === 'update' &&
- formData.value?.status === MesWmTransferStatusEnum.PREPARE,
-);
-const getTitle = computed(() => {
- switch (formType.value) {
- case 'confirm': {
- return '鍒拌揣纭';
- }
- case 'detail': {
- return $t('ui.actionTitle.view', ['杞Щ鍗�']);
- }
- case 'finish': {
- return '鎵ц杞Щ';
- }
- case 'stock': {
- return '鎵ц涓婃灦';
- }
- case 'update': {
- return $t('ui.actionTitle.edit', ['杞Щ鍗�']);
- }
- default: {
- return $t('ui.actionTitle.create', ['杞Щ鍗�']);
- }
- }
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 110,
- },
- layout: 'horizontal',
- schema: [],
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-/** 鎻愪氦杞Щ鍗曪細琛ㄥ崟鏈変慨鏀规椂鍏堜繚瀛橈紝鍐嶈皟鐢ㄦ彁浜ゆ帴鍙� */
-async function handleSubmit() {
- const { valid } = await formApi.validate();
- if (!valid || !formData.value?.id) {
- return;
- }
- modalApi.lock();
- try {
- const current = JSON.stringify(await formApi.getValues());
- if (current !== originalSnapshot.value) {
- const data = (await formApi.getValues()) as MesWmTransferApi.Transfer;
- await updateTransfer({ ...formData.value, ...data });
- originalSnapshot.value = current;
- }
- await submitTransfer(formData.value.id);
- message.success('鎻愪氦鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-/** 鍒拌揣纭 */
-async function handleConfirm() {
- if (!formData.value?.id) {
- return;
- }
- modalApi.lock();
- try {
- await confirmTransfer(formData.value.id);
- message.success('纭鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-/** 鎵ц涓婃灦 */
-async function handleStock() {
- if (!formData.value?.id) {
- return;
- }
- modalApi.lock();
- try {
- await stockTransfer(formData.value.id);
- message.success('涓婃灦鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-/** 鎵ц杞Щ */
-async function handleFinish() {
- if (!formData.value?.id) {
- return;
- }
- modalApi.lock();
- try {
- await finishTransfer(formData.value.id);
- message.success('鎵ц鎴愬姛');
- await modalApi.close();
- emit('success');
- } finally {
- modalApi.unlock();
- }
-}
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- if (!isEditable.value) {
- await modalApi.close();
- return;
- }
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data = (await formApi.getValues()) as MesWmTransferApi.Transfer;
- try {
- if (formData.value?.id) {
- await updateTransfer({ ...formData.value, ...data });
- formData.value = { ...formData.value, ...data };
- } else {
- const id = await createTransfer(data);
- formData.value = {
- ...data,
- id,
- status: MesWmTransferStatusEnum.PREPARE,
- };
- formType.value = 'update';
- // 鍒涘缓鎴愬姛鍚庡垏鎹㈢紪杈戞�侊紝閲嶆寕 schema 骞跺洖濉富閿� / 鐘舵��
- formApi.setState({ schema: useFormSchema(formType.value, formApi) });
- await formApi.setValues(formData.value);
- }
- originalSnapshot.value = JSON.stringify(await formApi.getValues());
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- originalSnapshot.value = '';
- return;
- }
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{ formType: FormType; id?: number }>();
- formType.value = data.formType;
- formApi.setState({ schema: useFormSchema(formType.value, formApi) });
- modalApi.setState({ showConfirmButton: isEditable.value });
- if (data?.id) {
- modalApi.lock();
- try {
- formData.value = await getTransfer(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- }
- originalSnapshot.value = JSON.stringify(await formApi.getValues());
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- <!-- 闈炴柊寤烘ā寮忓睍绀虹墿鏂欎俊鎭� -->
- <template v-if="formData?.id">
- <Divider>鐗╂枡淇℃伅</Divider>
- <div class="mx-4">
- <LineList :form-type="formType" :transfer-id="formData.id" />
- </div>
- </template>
- <template #prepend-footer>
- <div class="flex flex-auto items-center gap-2">
- <Popconfirm
- v-if="canSubmit"
- title="纭鎻愪氦璇ヨ浆绉诲崟锛熴�愭彁浜ゅ悗灏嗕笉鑳戒慨鏀广��"
- @confirm="handleSubmit"
- >
- <Button type="primary">鎻愪氦</Button>
- </Popconfirm>
- <Popconfirm
- v-if="isConfirm"
- title="纭鍒拌揣鍚庯紝灏嗚繘鍏ュ緟涓婃灦鐘舵�侊紝鏄惁缁х画锛�"
- @confirm="handleConfirm"
- >
- <Button type="primary">鍒拌揣纭</Button>
- </Popconfirm>
- <Popconfirm
- v-if="isStock"
- title="纭鎵ц涓婃灦锛�"
- @confirm="handleStock"
- >
- <Button type="primary">鎵ц涓婃灦</Button>
- </Popconfirm>
- <Popconfirm
- v-if="isFinish"
- title="纭鎵ц璋冩嫧锛熸墽琛屽悗灏嗘洿鏂板簱瀛樸��"
- @confirm="handleFinish"
- >
- <Button type="primary">鎵ц杞Щ</Button>
- </Popconfirm>
- </div>
- </template>
- </Modal>
-</template>
diff --git a/src/views/transfer/modules/line-form.vue b/src/views/transfer/modules/line-form.vue
deleted file mode 100644
index c4c41f6..0000000
--- a/src/views/transfer/modules/line-form.vue
+++ /dev/null
@@ -1,102 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmTransferLineApi } from '#/api/mes/wm/transfer/line';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import { getMaterialStock } from '#/api/mes/wm/materialstock';
-import {
- createTransferLine,
- getTransferLine,
- updateTransferLine,
-} from '#/api/mes/wm/transfer/line';
-import { $t } from '#/locales';
-
-import { useLineFormSchema } from '../data';
-
-const emit = defineEmits(['success']);
-const formData = ref<MesWmTransferLineApi.TransferLine>();
-const transferId = ref<number>(); // 鎵�灞炶浆绉诲崟缂栧彿
-
-const getTitle = computed(() => {
- return formData.value?.id
- ? $t('ui.actionTitle.edit', ['璋冩嫧鐗╂枡'])
- : $t('ui.actionTitle.create', ['璋冩嫧鐗╂枡']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 90,
- },
- layout: 'horizontal',
- schema: [],
- showDefaultActions: false,
- wrapperClass: 'grid-cols-3',
-});
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data =
- (await formApi.getValues()) as MesWmTransferLineApi.TransferLine;
- data.transferId = transferId.value;
- try {
- await (formData.value?.id
- ? updateTransferLine({ ...data, id: formData.value.id })
- : createTransferLine(data));
- // 鍏抽棴骞舵彁绀�
- await modalApi.close();
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- return;
- }
- formApi.setState({ schema: useLineFormSchema(formApi) });
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{ id?: number; transferId: number }>();
- transferId.value = data.transferId;
- if (!data.id) {
- return;
- }
- modalApi.lock();
- try {
- formData.value = await getTransferLine(data.id);
- // 缂栬緫鏃舵寜褰撳墠搴撳瓨鍦ㄥ簱閲忎綔涓烘暟閲忎笂闄�
- let quantityMax: number | undefined;
- if (formData.value.materialStockId) {
- const stock = await getMaterialStock(formData.value.materialStockId);
- quantityMax = stock?.quantity;
- }
- // 璁剧疆鍒� values
- await formApi.setValues({ ...formData.value, quantityMax });
- } finally {
- modalApi.unlock();
- }
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- </Modal>
-</template>
diff --git a/src/views/transfer/modules/line-list.vue b/src/views/transfer/modules/line-list.vue
deleted file mode 100644
index 05d8165..0000000
--- a/src/views/transfer/modules/line-list.vue
+++ /dev/null
@@ -1,228 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmTransferDetailApi } from '#/api/mes/wm/transfer/detail';
-import type { MesWmTransferLineApi } from '#/api/mes/wm/transfer/line';
-
-import { computed, reactive } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-
-import { message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import { getTransferDetailListByLineId } from '#/api/mes/wm/transfer/detail';
-import {
- deleteTransferLine,
- getTransferLineList,
-} from '#/api/mes/wm/transfer/line';
-import { $t } from '#/locales';
-import { PrinterLabel } from '#/views/wls/barcode/components';
-
-import { useLineGridColumns } from '../data';
-import DetailForm from './detail-form.vue';
-import DetailList from './detail-list.vue';
-import LineForm from './line-form.vue';
-
-const props = defineProps<{
- formType: FormType;
- transferId: number;
-}>();
-
-const isEditable = computed(() =>
- ['create', 'update'].includes(props.formType),
-); // 鏄惁鍙紪杈戣皟鎷ㄧ墿鏂欒
-const isStock = computed(() => props.formType === 'stock'); // 鏄惁涓轰笂鏋舵ā寮�
-const detailMap = reactive<
- Record<number, MesWmTransferDetailApi.TransferDetail[]>
->({}); // 宸插睍寮�琛岀殑璋冩嫧鏄庣粏缂撳瓨
-
-const [LineFormModal, lineFormModalApi] = useVbenModal({
- connectedComponent: LineForm,
- destroyOnClose: true,
-});
-
-const [DetailFormModal, detailFormModalApi] = useVbenModal({
- connectedComponent: DetailForm,
- destroyOnClose: true,
-});
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- for (const id of Object.keys(detailMap)) {
- delete detailMap[Number(id)];
- }
- gridApi.query();
-}
-
-/** 娣诲姞璋冩嫧鐗╂枡 */
-function handleCreate() {
- lineFormModalApi.setData({ transferId: props.transferId }).open();
-}
-
-/** 缂栬緫璋冩嫧鐗╂枡 */
-function handleEdit(row: MesWmTransferLineApi.TransferLine) {
- lineFormModalApi.setData({ id: row.id, transferId: props.transferId }).open();
-}
-
-/** 鍒犻櫎璋冩嫧鐗╂枡 */
-async function handleDelete(row: MesWmTransferLineApi.TransferLine) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.itemName]),
- duration: 0,
- });
- try {
- await deleteTransferLine(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.itemName]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-/** 涓婃灦锛氱洿鎺ユ墦寮�鏄庣粏鏂板琛ㄥ崟 */
-function handleStock(row: MesWmTransferLineApi.TransferLine) {
- openDetailForm(row.id!, row.itemId);
-}
-
-/** 鎵撳紑璋冩嫧鏄庣粏琛ㄥ崟 */
-function openDetailForm(lineId: number, itemId?: number, detailId?: number) {
- detailFormModalApi
- .setData({ detailId, itemId, lineId, transferId: props.transferId })
- .open();
-}
-
-/** 鑾峰彇宸插睍寮�琛岀殑璋冩嫧鏄庣粏 */
-function getExpandedDetails(row: MesWmTransferLineApi.TransferLine) {
- return detailMap[row.id!] || [];
-}
-
-/** 鍔犺浇鎸囧畾琛岀殑璋冩嫧鏄庣粏 */
-async function loadLineDetails(lineId: number) {
- detailMap[lineId] = await getTransferDetailListByLineId(lineId);
-}
-
-/** 灞曞紑琛屾椂鎳掑姞杞借皟鎷ㄦ槑缁� */
-async function handleExpandChange(
- row: MesWmTransferLineApi.TransferLine,
- expanded: boolean,
-) {
- if (!expanded) {
- return;
- }
- await loadLineDetails(row.id!);
-}
-
-/** 鏄庣粏琛ㄥ崟鎻愪氦鎴愬姛鍚庯紝鍒锋柊瀵瑰簲琛屽凡灞曞紑鐨勬槑缁� */
-async function handleDetailSuccess(lineId: number) {
- await loadLineDetails(lineId);
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- gridOptions: {
- columns: useLineGridColumns(isEditable.value, isStock.value),
- expandConfig: {
- padding: true,
- },
- height: 400,
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async () => {
- if (!props.transferId) {
- return [];
- }
- return await getTransferLineList(props.transferId);
- },
- },
- },
- pagerConfig: {
- enabled: false,
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- },
- } as VxeTableGridOptions<MesWmTransferLineApi.TransferLine>,
- gridEvents: {
- toggleRowExpand: ({
- expanded,
- row,
- }: {
- expanded: boolean;
- row: MesWmTransferLineApi.TransferLine;
- }) => {
- handleExpandChange(row, expanded);
- },
- },
-});
-</script>
-
-<template>
- <div>
- <LineFormModal @success="handleRefresh" />
- <DetailFormModal @success="handleDetailSuccess" />
- <Grid table-title="鐗╂枡淇℃伅">
- <template v-if="isEditable" #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: '娣诲姞璋冩嫧鐗╂枡',
- type: 'primary',
- icon: ACTION_ICON.ADD,
- onClick: handleCreate,
- },
- ]"
- />
- </template>
- <template #detail="{ row }">
- <DetailList
- :details="getExpandedDetails(row)"
- :form-type="formType"
- @edit="(detailId) => openDetailForm(row.id!, row.itemId, detailId)"
- @refresh="loadLineDetails(row.id!)"
- />
- </template>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- ifShow: isEditable,
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- ifShow: isEditable,
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.itemName]),
- confirm: handleDelete.bind(null, row),
- },
- },
- {
- label: '涓婃灦',
- type: 'link',
- ifShow: isStock,
- onClick: handleStock.bind(null, row),
- },
- ]"
- />
- <PrinterLabel
- v-if="isStock"
- :biz-code="row.batchCode"
- :biz-id="row.batchId"
- biz-type="BATCH"
- />
- </template>
- </Grid>
- </div>
-</template>
diff --git a/src/views/warehouse/area/data.ts b/src/views/warehouse/area/data.ts
deleted file mode 100644
index 0d2d766..0000000
--- a/src/views/warehouse/area/data.ts
+++ /dev/null
@@ -1,338 +0,0 @@
-import type { VbenFormApi, VbenFormSchema } from '#/adapter/form';
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmWarehouseAreaApi } from '#/api/mes/wm/warehouse/area';
-
-import { h } from 'vue';
-
-import {
- CommonStatusEnum,
- DICT_TYPE,
- MesAutoCodeRuleCode,
-} from '@vben/constants';
-import { getDictOptions } from '@vben/hooks';
-
-import { Button } from 'ant-design-vue';
-
-import { z } from '#/adapter/form';
-import { generateAutoCode } from '#/api/mes/md/autocode/record';
-import { getWarehouseSimpleList } from '#/api/mes/wm/warehouse';
-import { getWarehouseLocationSimpleList } from '#/api/mes/wm/warehouse/location';
-
-/** 琛ㄥ崟绫诲瀷 */
-export type FormType = 'create' | 'detail' | 'update';
-
-/** 鏂板/淇敼鐨勮〃鍗� */
-export function useFormSchema(
- formType: FormType,
- formApi?: VbenFormApi,
-): VbenFormSchema[] {
- return [
- {
- fieldName: 'id',
- component: 'Input',
- dependencies: { triggerFields: [''], show: () => false },
- },
- {
- fieldName: 'warehouseId',
- label: '鎵�灞炰粨搴�',
- component: 'ApiSelect',
- componentProps: {
- allowClear: true,
- api: getWarehouseSimpleList,
- labelField: 'name',
- valueField: 'id',
- placeholder: '璇烽�夋嫨浠撳簱',
- // 浠撳簱鍙樻洿鏃舵竻绌烘墍灞炲簱鍖�
- onChange: () => formApi?.setFieldValue('locationId', undefined),
- },
- },
- {
- fieldName: 'locationId',
- label: '鎵�灞炲簱鍖�',
- component: 'ApiSelect',
- dependencies: {
- triggerFields: ['warehouseId'],
- componentProps: (values) => ({
- allowClear: true,
- api: () =>
- getWarehouseLocationSimpleList(values.warehouseId as number),
- // 鏀瑰彉 warehouseId 鏃跺己鍒跺埛鏂伴�夐」
- params: { warehouseId: values.warehouseId },
- disabled: !values.warehouseId,
- labelField: 'name',
- valueField: 'id',
- placeholder: '璇烽�夋嫨搴撳尯',
- }),
- },
- rules: 'required',
- },
- {
- fieldName: 'code',
- label: '搴撲綅缂栫爜',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ュ簱浣嶇紪鐮�',
- },
- rules: 'required',
- suffix:
- formType === 'detail'
- ? undefined
- : () =>
- h(
- Button,
- {
- type: 'default',
- onClick: async () => {
- const code = await generateAutoCode(
- MesAutoCodeRuleCode.WM_AREA_CODE,
- );
- await formApi?.setFieldValue('code', code);
- },
- },
- { default: () => '鑷姩鐢熸垚' },
- ),
- },
- {
- fieldName: 'name',
- label: '搴撲綅鍚嶇О',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ュ簱浣嶅悕绉�',
- },
- rules: 'required',
- },
- {
- fieldName: 'area',
- label: '闈㈢Н锛堛帯锛�',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0,
- precision: 2,
- placeholder: '璇疯緭鍏ラ潰绉�',
- },
- },
- {
- fieldName: 'maxLoad',
- label: '鏈�澶ц浇閲�',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0,
- precision: 2,
- placeholder: '璇疯緭鍏ユ渶澶ц浇閲�',
- },
- },
- {
- fieldName: 'positionX',
- label: '浣嶇疆 X',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0,
- placeholder: '璇疯緭鍏ヤ綅缃� X',
- },
- },
- {
- fieldName: 'positionY',
- label: '浣嶇疆 Y',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0,
- placeholder: '璇疯緭鍏ヤ綅缃� Y',
- },
- },
- {
- fieldName: 'positionZ',
- label: '浣嶇疆 Z',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0,
- placeholder: '璇疯緭鍏ヤ綅缃� Z',
- },
- },
- {
- fieldName: 'status',
- label: '鐘舵��',
- component: 'Select',
- componentProps: {
- options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'),
- placeholder: '璇烽�夋嫨',
- },
- rules: z.number().default(CommonStatusEnum.ENABLE),
- },
- {
- fieldName: 'frozen',
- label: '鏄惁鍐荤粨',
- component: 'Switch',
- componentProps: {
- checkedChildren: '鏄�',
- unCheckedChildren: '鍚�',
- },
- rules: z.boolean().default(false),
- },
- {
- fieldName: 'allowItemMixing',
- label: '鍏佽鐗╂枡娣锋斁',
- component: 'Switch',
- componentProps: {
- checkedChildren: '鏄�',
- unCheckedChildren: '鍚�',
- },
- rules: z.boolean().default(true),
- },
- {
- fieldName: 'allowBatchMixing',
- label: '鍏佽鎵规娣锋斁',
- component: 'Switch',
- componentProps: {
- checkedChildren: '鏄�',
- unCheckedChildren: '鍚�',
- },
- rules: z.boolean().default(true),
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勬悳绱㈣〃鍗� */
-export function useGridFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'code',
- label: '搴撲綅缂栫爜',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ュ簱浣嶇紪鐮�',
- },
- },
- {
- fieldName: 'name',
- label: '搴撲綅鍚嶇О',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ュ簱浣嶅悕绉�',
- },
- },
- {
- fieldName: 'positionX',
- label: '浣嶇疆 X',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0,
- placeholder: '璇疯緭鍏ヤ綅缃� X',
- },
- },
- {
- fieldName: 'positionY',
- label: '浣嶇疆 Y',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0,
- placeholder: '璇疯緭鍏ヤ綅缃� Y',
- },
- },
- {
- fieldName: 'positionZ',
- label: '浣嶇疆 Z',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0,
- placeholder: '璇疯緭鍏ヤ綅缃� Z',
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勫瓧娈� */
-export function useGridColumns(): VxeTableGridOptions<MesWmWarehouseAreaApi.WarehouseArea>['columns'] {
- return [
- {
- field: 'code',
- title: '搴撲綅缂栫爜',
- minWidth: 140,
- slots: { default: 'code' },
- },
- {
- field: 'name',
- title: '搴撲綅鍚嶇О',
- minWidth: 160,
- },
- {
- field: 'area',
- title: '闈㈢Н锛堛帯锛�',
- width: 100,
- },
- {
- field: 'maxLoad',
- title: '鏈�澶ц浇閲�',
- width: 100,
- },
- {
- field: 'positionX',
- title: '浣嶇疆 X',
- width: 80,
- },
- {
- field: 'positionY',
- title: '浣嶇疆 Y',
- width: 80,
- },
- {
- field: 'positionZ',
- title: '浣嶇疆 Z',
- width: 80,
- },
- {
- field: 'status',
- title: '鐘舵��',
- width: 90,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.COMMON_STATUS },
- },
- },
- {
- field: 'frozen',
- title: '鍐荤粨',
- width: 90,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.INFRA_BOOLEAN_STRING },
- },
- },
- {
- field: 'remark',
- title: '澶囨敞',
- minWidth: 180,
- },
- {
- field: 'createTime',
- title: '鍒涘缓鏃堕棿',
- width: 180,
- formatter: 'formatDateTime',
- },
- {
- title: '鎿嶄綔',
- width: 200,
- fixed: 'right',
- slots: { default: 'actions' },
- },
- ];
-}
diff --git a/src/views/warehouse/area/index.vue b/src/views/warehouse/area/index.vue
deleted file mode 100644
index be5e514..0000000
--- a/src/views/warehouse/area/index.vue
+++ /dev/null
@@ -1,211 +0,0 @@
-<script lang="ts" setup>
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmWarehouseAreaApi } from '#/api/mes/wm/warehouse/area';
-
-import { ref } from 'vue';
-import { useRoute } from 'vue-router';
-
-import { Page, useVbenModal } from '@vben/common-ui';
-import { BarcodeBizTypeEnum } from '@vben/constants';
-
-import { Alert, Button, message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import {
- deleteWarehouseArea,
- getWarehouseAreaPage,
-} from '#/api/mes/wm/warehouse/area';
-import { getWarehouseLocation } from '#/api/mes/wm/warehouse/location';
-import { $t } from '#/locales';
-
-import { BarcodeDetail } from '../../barcode/components';
-import { useGridColumns, useGridFormSchema } from './data';
-import Form from './modules/form.vue';
-
-const route = useRoute();
-
-const [FormModal, formModalApi] = useVbenModal({
- connectedComponent: Form,
- destroyOnClose: true,
-});
-
-const barcodeDetailRef = ref<InstanceType<typeof BarcodeDetail>>();
-
-/** 褰撳墠搴撳尯涓婁笅鏂囷紙鍚屾浠� URL 瑙f瀽锛岀‘淇濋娆℃煡璇㈠甫寰椾笂 locationId锛� */
-const currentLocation = ref<{
- id: number;
- name: string;
- warehouseId: number;
- warehouseName: string;
-}>(
- (() => {
- const id = Number(route.query.locationId);
- return Number.isInteger(id) && id > 0
- ? { id, name: '', warehouseId: 0, warehouseName: '' }
- : { id: 0, name: '', warehouseId: 0, warehouseName: '' };
- })(),
-);
-
-/** 寮傛鍔犺浇搴撳尯/浠撳簱鍚嶇О锛堜笉闃诲鍒楄〃鏌ヨ锛� */
-async function loadLocationName() {
- if (!currentLocation.value.id) {
- return;
- }
- try {
- const location = await getWarehouseLocation(currentLocation.value.id);
- currentLocation.value.name = location.name || '';
- currentLocation.value.warehouseId = location.warehouseId || 0;
- currentLocation.value.warehouseName = location.warehouseName || '';
- } catch {
- // 蹇界暐涓婄骇鍚嶇О鍔犺浇寮傚父锛屼笉褰卞搷鍒楄〃鏌ヨ
- }
-}
-loadLocationName();
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- gridApi.query();
-}
-
-/** 鍒涘缓搴撲綅 */
-function handleCreate() {
- formModalApi
- .setData({
- formType: 'create',
- locationId: currentLocation.value.id || undefined,
- warehouseId: currentLocation.value.warehouseId || undefined,
- })
- .open();
-}
-
-/** 鏌ョ湅搴撲綅璇︽儏 */
-function handleDetail(row: MesWmWarehouseAreaApi.WarehouseArea) {
- formModalApi.setData({ formType: 'detail', id: row.id }).open();
-}
-
-/** 缂栬緫搴撲綅 */
-function handleEdit(row: MesWmWarehouseAreaApi.WarehouseArea) {
- formModalApi.setData({ formType: 'update', id: row.id }).open();
-}
-
-/** 鍒犻櫎搴撲綅 */
-async function handleDelete(row: MesWmWarehouseAreaApi.WarehouseArea) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.name]),
- duration: 0,
- });
- try {
- await deleteWarehouseArea(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.name]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-/** 鏌ョ湅搴撲綅鏉$爜 */
-function handleBarcode(row: MesWmWarehouseAreaApi.WarehouseArea) {
- barcodeDetailRef.value?.openByBusiness(
- row.id!,
- BarcodeBizTypeEnum.AREA,
- row.code,
- row.name,
- );
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- formOptions: {
- schema: useGridFormSchema(),
- },
- gridOptions: {
- columns: useGridColumns(),
- height: 'auto',
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }, formValues) => {
- return await getWarehouseAreaPage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- locationId: currentLocation.value.id || undefined,
- ...formValues,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- search: true,
- },
- } as VxeTableGridOptions<MesWmWarehouseAreaApi.WarehouseArea>,
-});
-</script>
-
-<template>
- <Page auto-content-height><FormModal @success="handleRefresh" />
- <BarcodeDetail ref="barcodeDetailRef" />
-
- <Alert
- v-if="currentLocation.id"
- class="mb-3"
- :message="`褰撳墠浠撳簱/搴撳尯锛�${currentLocation.warehouseName || `#${currentLocation.warehouseId || '-'}`} / ${currentLocation.name || `#${currentLocation.id}`}`"
- show-icon
- type="info"
- />
-
- <Grid table-title="搴撲綅鍒楄〃">
- <template #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: $t('ui.actionTitle.create', ['搴撲綅']),
- type: 'primary',
- icon: ACTION_ICON.ADD,
- auth: ['mes:wm-warehouse:create'],
- onClick: handleCreate,
- },
- ]"
- />
- </template>
- <template #code="{ row }">
- <Button type="link" @click="handleDetail(row)">
- {{ row.code }}
- </Button>
- </template>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- auth: ['mes:wm-warehouse:update'],
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- auth: ['mes:wm-warehouse:delete'],
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.name]),
- confirm: handleDelete.bind(null, row),
- },
- },
- {
- label: '鏉$爜',
- type: 'link',
- auth: ['mes:wm-warehouse:query'],
- onClick: handleBarcode.bind(null, row),
- },
- ]"
- />
- </template>
- </Grid>
- </Page>
-</template>
diff --git a/src/views/warehouse/area/modules/form.vue b/src/views/warehouse/area/modules/form.vue
deleted file mode 100644
index f75c83c..0000000
--- a/src/views/warehouse/area/modules/form.vue
+++ /dev/null
@@ -1,149 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { MesWmWarehouseAreaApi } from '#/api/mes/wm/warehouse/area';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-import { BarcodeBizTypeEnum } from '@vben/constants';
-
-import { Button, message } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createWarehouseArea,
- getWarehouseArea,
- updateWarehouseArea,
-} from '#/api/mes/wm/warehouse/area';
-import { getWarehouseLocation } from '#/api/mes/wm/warehouse/location';
-import { $t } from '#/locales';
-import { BarcodeDetail } from '#/views/wls/barcode/components';
-
-import { useFormSchema } from '../data';
-
-const emit = defineEmits(['success']);
-const formType = ref<FormType>('create');
-const formData = ref<MesWmWarehouseAreaApi.WarehouseArea>();
-const barcodeDetailRef = ref<InstanceType<typeof BarcodeDetail>>();
-
-const getTitle = computed(() => {
- if (formType.value === 'detail') {
- return $t('ui.actionTitle.view', ['搴撲綅']);
- }
- return formType.value === 'update'
- ? $t('ui.actionTitle.edit', ['搴撲綅'])
- : $t('ui.actionTitle.create', ['搴撲綅']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 120,
- },
- wrapperClass: 'grid-cols-3',
- layout: 'horizontal',
- schema: [],
- showDefaultActions: false,
-});
-
-/** 鏌ョ湅鏉$爜 */
-function handleBarcode() {
- if (!formData.value?.id) {
- return;
- }
- barcodeDetailRef.value?.openByBusiness(
- formData.value.id,
- BarcodeBizTypeEnum.AREA,
- formData.value.code,
- formData.value.name,
- );
-}
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- if (formType.value === 'detail') {
- await modalApi.close();
- return;
- }
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data =
- (await formApi.getValues()) as MesWmWarehouseAreaApi.WarehouseArea;
- try {
- await (formData.value?.id
- ? updateWarehouseArea(data)
- : createWarehouseArea(data));
- // 鍏抽棴骞舵彁绀�
- await modalApi.close();
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- return;
- }
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{
- formType: FormType;
- id?: number;
- locationId?: number;
- warehouseId?: number;
- }>();
- formType.value = data.formType;
- formApi.setState({ schema: useFormSchema(formType.value, formApi) });
- formApi.setDisabled(formType.value === 'detail');
- modalApi.setState({ showConfirmButton: formType.value !== 'detail' });
- if (data?.id) {
- modalApi.lock();
- try {
- formData.value = await getWarehouseArea(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- return;
- }
- // 鏂板鎬侊細鏍规嵁鐖剁骇涓婁笅鏂囧甫鍏ヤ粨搴�/搴撳尯
- let warehouseId = data?.warehouseId;
- if (data?.locationId) {
- if (!warehouseId) {
- try {
- const location = await getWarehouseLocation(data.locationId);
- warehouseId = location.warehouseId;
- } catch {
- // 蹇界暐
- }
- }
- await formApi.setValues({
- warehouseId,
- locationId: data.locationId,
- });
- } else if (warehouseId) {
- await formApi.setFieldValue('warehouseId', warehouseId);
- }
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- <template v-if="formType === 'detail' && formData?.id" #prepend-footer>
- <Button @click="handleBarcode"> 鏌ョ湅鏉$爜 </Button>
- </template>
- <BarcodeDetail ref="barcodeDetailRef" />
- </Modal>
-</template>
diff --git a/src/views/warehouse/components/area-select.vue b/src/views/warehouse/components/area-select.vue
deleted file mode 100644
index b423ae7..0000000
--- a/src/views/warehouse/components/area-select.vue
+++ /dev/null
@@ -1,114 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmWarehouseAreaApi } from '#/api/mes/wm/warehouse/area';
-
-import { computed, ref, useAttrs, watch, watchEffect } from 'vue';
-
-import { Select, SelectOption, Tag, Tooltip } from 'ant-design-vue';
-
-import { getWarehouseAreaSimpleList } from '#/api/mes/wm/warehouse/area';
-
-defineOptions({ name: 'WmWarehouseAreaSelect', inheritAttrs: false });
-
-const props = withDefaults(
- defineProps<{
- allowClear?: boolean;
- disabled?: boolean;
- locationId?: number;
- modelValue?: number;
- placeholder?: string;
- }>(),
- {
- allowClear: true,
- disabled: false,
- locationId: undefined,
- modelValue: undefined,
- placeholder: '璇烽�夋嫨搴撲綅',
- },
-);
-
-const emit = defineEmits<{
- change: [item: MesWmWarehouseAreaApi.WarehouseArea | undefined];
- 'update:modelValue': [value: number | undefined];
-}>();
-
-const attrs = useAttrs();
-const allList = ref<MesWmWarehouseAreaApi.WarehouseArea[]>([]);
-const selectedItem = ref<MesWmWarehouseAreaApi.WarehouseArea>();
-
-const selectValue = computed({
- get: () => props.modelValue,
- set: (val) => emit('update:modelValue', val),
-});
-
-/** 閫変腑鍙樺寲 */
-function handleChange(val: any) {
- const item = allList.value.find((o) => o.id === val);
- selectedItem.value = item;
- emit('change', item);
-}
-
-/** 鍓嶇杩囨护锛坣ame + code锛� */
-function filterOption(input: string, option: any) {
- const item = allList.value.find((o) => o.id === option.value);
- if (!item) {
- return false;
- }
- const keyword = input.toLowerCase();
- return (
- !!item.name?.toLowerCase().includes(keyword) ||
- !!item.code?.toLowerCase().includes(keyword)
- );
-}
-
-watch(
- () => props.modelValue,
- (val) => {
- if (val === null) {
- selectedItem.value = undefined;
- return;
- }
- if (selectedItem.value?.id !== val && allList.value.length > 0) {
- selectedItem.value = allList.value.find((o) => o.id === val);
- }
- },
-);
-
-/** 搴撳尯鍙樻洿鎴栧垵濮嬪寲鏃堕噸鏂板姞杞藉簱浣嶅垪琛� */
-watchEffect(async () => {
- allList.value = await getWarehouseAreaSimpleList(props.locationId);
- if (props.modelValue !== null) {
- selectedItem.value = allList.value.find((o) => o.id === props.modelValue);
- }
-});
-</script>
-
-<template>
- <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>鎵�灞炰粨搴擄細{{ selectedItem.warehouseName || '-' }}</div>
- <div>鎵�灞炲簱鍖猴細{{ selectedItem.locationName || '-' }}</div>
- </div>
- </template>
- <Select
- v-bind="attrs"
- v-model:value="selectValue"
- :allow-clear="allowClear"
- class="!w-full"
- :disabled="disabled"
- :filter-option="filterOption"
- :placeholder="placeholder"
- show-search
- @change="handleChange"
- >
- <SelectOption v-for="item in allList" :key="item.id" :value="item.id">
- <div class="flex items-center gap-2">
- <span>{{ item.name }}</span>
- <Tag v-if="item.code" color="blue">缂栧彿: {{ item.code }}</Tag>
- </div>
- </SelectOption>
- </Select>
- </Tooltip>
-</template>
diff --git a/src/views/warehouse/components/index.ts b/src/views/warehouse/components/index.ts
deleted file mode 100644
index a2019df..0000000
--- a/src/views/warehouse/components/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export { default as WmWarehouseAreaSelect } from './area-select.vue';
-export { default as WmWarehouseLocationSelect } from './location-select.vue';
-export { default as WmWarehouseSelect } from './select.vue';
diff --git a/src/views/warehouse/components/location-select.vue b/src/views/warehouse/components/location-select.vue
deleted file mode 100644
index d732a9e..0000000
--- a/src/views/warehouse/components/location-select.vue
+++ /dev/null
@@ -1,113 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmWarehouseLocationApi } from '#/api/mes/wm/warehouse/location';
-
-import { computed, ref, useAttrs, watch, watchEffect } from 'vue';
-
-import { Select, SelectOption, Tag, Tooltip } from 'ant-design-vue';
-
-import { getWarehouseLocationSimpleList } from '#/api/mes/wm/warehouse/location';
-
-defineOptions({ name: 'WmWarehouseLocationSelect', inheritAttrs: false });
-
-const props = withDefaults(
- defineProps<{
- allowClear?: boolean;
- disabled?: boolean;
- modelValue?: number;
- placeholder?: string;
- warehouseId?: number;
- }>(),
- {
- allowClear: true,
- disabled: false,
- modelValue: undefined,
- placeholder: '璇烽�夋嫨搴撳尯',
- warehouseId: undefined,
- },
-);
-
-const emit = defineEmits<{
- change: [item: MesWmWarehouseLocationApi.WarehouseLocation | undefined];
- 'update:modelValue': [value: number | undefined];
-}>();
-
-const attrs = useAttrs();
-const allList = ref<MesWmWarehouseLocationApi.WarehouseLocation[]>([]);
-const selectedItem = ref<MesWmWarehouseLocationApi.WarehouseLocation>();
-
-const selectValue = computed({
- get: () => props.modelValue,
- set: (val) => emit('update:modelValue', val),
-});
-
-/** 閫変腑鍙樺寲 */
-function handleChange(val: any) {
- const item = allList.value.find((o) => o.id === val);
- selectedItem.value = item;
- emit('change', item);
-}
-
-/** 鍓嶇杩囨护锛坣ame + code锛� */
-function filterOption(input: string, option: any) {
- const item = allList.value.find((o) => o.id === option.value);
- if (!item) {
- return false;
- }
- const keyword = input.toLowerCase();
- return (
- !!item.name?.toLowerCase().includes(keyword) ||
- !!item.code?.toLowerCase().includes(keyword)
- );
-}
-
-watch(
- () => props.modelValue,
- (val) => {
- if (val === null) {
- selectedItem.value = undefined;
- return;
- }
- if (selectedItem.value?.id !== val && allList.value.length > 0) {
- selectedItem.value = allList.value.find((o) => o.id === val);
- }
- },
-);
-
-/** 浠撳簱鍙樻洿鎴栧垵濮嬪寲鏃堕噸鏂板姞杞藉簱鍖哄垪琛� */
-watchEffect(async () => {
- allList.value = await getWarehouseLocationSimpleList(props.warehouseId);
- if (props.modelValue !== null) {
- selectedItem.value = allList.value.find((o) => o.id === props.modelValue);
- }
-});
-</script>
-
-<template>
- <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>鎵�灞炰粨搴擄細{{ selectedItem.warehouseName || '-' }}</div>
- </div>
- </template>
- <Select
- v-bind="attrs"
- v-model:value="selectValue"
- :allow-clear="allowClear"
- class="!w-full"
- :disabled="disabled"
- :filter-option="filterOption"
- :placeholder="placeholder"
- show-search
- @change="handleChange"
- >
- <SelectOption v-for="item in allList" :key="item.id" :value="item.id">
- <div class="flex items-center gap-2">
- <span>{{ item.name }}</span>
- <Tag v-if="item.code" color="blue">缂栧彿: {{ item.code }}</Tag>
- </div>
- </SelectOption>
- </Select>
- </Tooltip>
-</template>
diff --git a/src/views/warehouse/components/select.vue b/src/views/warehouse/components/select.vue
deleted file mode 100644
index 339f6b8..0000000
--- a/src/views/warehouse/components/select.vue
+++ /dev/null
@@ -1,110 +0,0 @@
-<script lang="ts" setup>
-import type { MesWmWarehouseApi } from '#/api/mes/wm/warehouse';
-
-import { computed, onMounted, ref, useAttrs, watch } from 'vue';
-
-import { Select, SelectOption, Tag, Tooltip } from 'ant-design-vue';
-
-import { getWarehouseSimpleList } from '#/api/mes/wm/warehouse';
-
-defineOptions({ name: 'WmWarehouseSelect', inheritAttrs: false });
-
-const props = withDefaults(
- defineProps<{
- allowClear?: boolean;
- disabled?: boolean;
- modelValue?: number;
- placeholder?: string;
- }>(),
- {
- allowClear: true,
- disabled: false,
- modelValue: undefined,
- placeholder: '璇烽�夋嫨浠撳簱',
- },
-);
-
-const emit = defineEmits<{
- change: [item: MesWmWarehouseApi.Warehouse | undefined];
- 'update:modelValue': [value: number | undefined];
-}>();
-
-const attrs = useAttrs();
-const allList = ref<MesWmWarehouseApi.Warehouse[]>([]);
-const selectedItem = ref<MesWmWarehouseApi.Warehouse>();
-
-const selectValue = computed({
- get: () => props.modelValue,
- set: (val) => emit('update:modelValue', val),
-});
-
-/** 閫変腑鍙樺寲 */
-function handleChange(val: any) {
- const item = allList.value.find((o) => o.id === val);
- selectedItem.value = item;
- emit('change', item);
-}
-
-/** 鍓嶇杩囨护锛坣ame + code锛� */
-function filterOption(input: string, option: any) {
- const item = allList.value.find((o) => o.id === option.value);
- if (!item) {
- return false;
- }
- const keyword = input.toLowerCase();
- return (
- !!item.name?.toLowerCase().includes(keyword) ||
- !!item.code?.toLowerCase().includes(keyword)
- );
-}
-
-watch(
- () => props.modelValue,
- (val) => {
- if (val === null) {
- selectedItem.value = undefined;
- return;
- }
- if (selectedItem.value?.id !== val && allList.value.length > 0) {
- selectedItem.value = allList.value.find((o) => o.id === val);
- }
- },
-);
-
-onMounted(async () => {
- allList.value = await getWarehouseSimpleList();
- if (props.modelValue !== null) {
- selectedItem.value = allList.value.find((o) => o.id === props.modelValue);
- }
-});
-</script>
-
-<template>
- <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>鍦板潃锛歿{ selectedItem.address || '-' }}</div>
- </div>
- </template>
- <Select
- v-bind="attrs"
- v-model:value="selectValue"
- :allow-clear="allowClear"
- class="!w-full"
- :disabled="disabled"
- :filter-option="filterOption"
- :placeholder="placeholder"
- show-search
- @change="handleChange"
- >
- <SelectOption v-for="item in allList" :key="item.id" :value="item.id">
- <div class="flex items-center gap-2">
- <span>{{ item.name }}</span>
- <Tag v-if="item.code" color="blue">缂栧彿: {{ item.code }}</Tag>
- </div>
- </SelectOption>
- </Select>
- </Tooltip>
-</template>
diff --git a/src/views/warehouse/data.ts b/src/views/warehouse/data.ts
deleted file mode 100644
index 6eaf201..0000000
--- a/src/views/warehouse/data.ts
+++ /dev/null
@@ -1,221 +0,0 @@
-import type { VbenFormApi, VbenFormSchema } from '#/adapter/form';
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmWarehouseApi } from '#/api/mes/wm/warehouse';
-import type { SystemUserApi } from '#/api/system/user';
-
-import { h } from 'vue';
-
-import { DICT_TYPE, MesAutoCodeRuleCode } from '@vben/constants';
-
-import { Button } from 'ant-design-vue';
-
-import { z } from '#/adapter/form';
-import { generateAutoCode } from '#/api/mes/md/autocode/record';
-import { getSimpleUserList } from '#/api/system/user';
-
-/** 琛ㄥ崟绫诲瀷 */
-export type FormType = 'create' | 'detail' | 'update';
-
-/** 鍏宠仈鏁版嵁 */
-let userList: SystemUserApi.User[] = [];
-getSimpleUserList().then((data) => (userList = data));
-
-/** 鏂板/淇敼鐨勮〃鍗� */
-export function useFormSchema(
- formType: FormType,
- formApi?: VbenFormApi,
-): VbenFormSchema[] {
- return [
- {
- fieldName: 'id',
- component: 'Input',
- dependencies: {
- triggerFields: [''],
- show: () => false,
- },
- },
- {
- fieldName: 'code',
- label: '浠撳簱缂栫爜',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ヤ粨搴撶紪鐮�',
- },
- rules: 'required',
- suffix:
- formType === 'detail'
- ? undefined
- : () =>
- h(
- Button,
- {
- type: 'default',
- onClick: async () => {
- const code = await generateAutoCode(
- MesAutoCodeRuleCode.WM_WAREHOUSE_CODE,
- );
- await formApi?.setFieldValue('code', code);
- },
- },
- { default: () => '鑷姩鐢熸垚' },
- ),
- },
- {
- fieldName: 'name',
- label: '浠撳簱鍚嶇О',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ヤ粨搴撳悕绉�',
- },
- rules: 'required',
- },
- {
- fieldName: 'chargeUserId',
- label: '璐熻矗浜�',
- component: 'ApiSelect',
- componentProps: {
- allowClear: true,
- api: getSimpleUserList,
- labelField: 'nickname',
- valueField: 'id',
- placeholder: '璇烽�夋嫨璐熻矗浜�',
- },
- },
- {
- fieldName: 'address',
- label: '浠撳簱鍦板潃',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ヤ粨搴撳湴鍧�',
- },
- },
- {
- fieldName: 'area',
- label: '闈㈢Н锛堛帯锛�',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0,
- precision: 2,
- placeholder: '璇疯緭鍏ラ潰绉�',
- },
- },
- {
- fieldName: 'frozen',
- label: '鏄惁鍐荤粨',
- component: 'Switch',
- componentProps: {
- checkedChildren: '鏄�',
- unCheckedChildren: '鍚�',
- },
- rules: z.boolean().default(false),
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勬悳绱㈣〃鍗� */
-export function useGridFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'code',
- label: '浠撳簱缂栫爜',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ヤ粨搴撶紪鐮�',
- },
- },
- {
- fieldName: 'name',
- label: '浠撳簱鍚嶇О',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ヤ粨搴撳悕绉�',
- },
- },
- {
- fieldName: 'frozen',
- label: '鏄惁鍐荤粨',
- component: 'Select',
- componentProps: {
- allowClear: true,
- options: [
- { label: '鏄�', value: true },
- { label: '鍚�', value: false },
- ],
- placeholder: '璇烽�夋嫨',
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勫瓧娈� */
-export function useGridColumns(): VxeTableGridOptions<MesWmWarehouseApi.Warehouse>['columns'] {
- return [
- {
- field: 'code',
- title: '浠撳簱缂栫爜',
- minWidth: 140,
- slots: { default: 'code' },
- },
- {
- field: 'name',
- title: '浠撳簱鍚嶇О',
- minWidth: 160,
- },
- {
- field: 'address',
- title: '浠撳簱鍦板潃',
- minWidth: 180,
- },
- {
- field: 'area',
- title: '闈㈢Н锛堛帯锛�',
- width: 110,
- },
- {
- field: 'chargeUserId',
- title: '璐熻矗浜�',
- width: 120,
- formatter: ({ cellValue }) =>
- userList.find((user) => user.id === cellValue)?.nickname ?? '',
- },
- {
- field: 'frozen',
- title: '鍐荤粨',
- width: 90,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.INFRA_BOOLEAN_STRING },
- },
- },
- {
- field: 'remark',
- title: '澶囨敞',
- minWidth: 180,
- },
- {
- field: 'createTime',
- title: '鍒涘缓鏃堕棿',
- width: 180,
- formatter: 'formatDateTime',
- },
- {
- title: '鎿嶄綔',
- width: 220,
- fixed: 'right',
- slots: { default: 'actions' },
- },
- ];
-}
diff --git a/src/views/warehouse/index.vue b/src/views/warehouse/index.vue
deleted file mode 100644
index 6762750..0000000
--- a/src/views/warehouse/index.vue
+++ /dev/null
@@ -1,175 +0,0 @@
-<script lang="ts" setup>
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmWarehouseApi } from '#/api/mes/wm/warehouse';
-
-import { ref } from 'vue';
-import { useRouter } from 'vue-router';
-
-import { Page, useVbenModal } from '@vben/common-ui';
-import { BarcodeBizTypeEnum } from '@vben/constants';
-
-import { Button, message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import { deleteWarehouse, getWarehousePage } from '#/api/mes/wm/warehouse';
-import { $t } from '#/locales';
-
-import { BarcodeDetail } from '../barcode/components';
-import { useGridColumns, useGridFormSchema } from './data';
-import Form from './modules/form.vue';
-
-const router = useRouter();
-
-const [FormModal, formModalApi] = useVbenModal({
- connectedComponent: Form,
- destroyOnClose: true,
-});
-
-const barcodeDetailRef = ref<InstanceType<typeof BarcodeDetail>>();
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- gridApi.query();
-}
-
-/** 鍒涘缓浠撳簱 */
-function handleCreate() {
- formModalApi.setData({ formType: 'create' }).open();
-}
-
-/** 鏌ョ湅浠撳簱璇︽儏 */
-function handleDetail(row: MesWmWarehouseApi.Warehouse) {
- formModalApi.setData({ formType: 'detail', id: row.id }).open();
-}
-
-/** 缂栬緫浠撳簱 */
-function handleEdit(row: MesWmWarehouseApi.Warehouse) {
- formModalApi.setData({ formType: 'update', id: row.id }).open();
-}
-
-/** 鍒犻櫎浠撳簱 */
-async function handleDelete(row: MesWmWarehouseApi.Warehouse) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.name]),
- duration: 0,
- });
- try {
- await deleteWarehouse(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.name]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-/** 璺宠浆搴撳尯鍒楄〃 */
-function handleOpenLocation(row: MesWmWarehouseApi.Warehouse) {
- router.push({
- name: 'MesWmLocation',
- query: { warehouseId: String(row.id) },
- });
-}
-
-/** 鏌ョ湅浠撳簱鏉$爜 */
-function handleBarcode(row: MesWmWarehouseApi.Warehouse) {
- barcodeDetailRef.value?.openByBusiness(
- row.id!,
- BarcodeBizTypeEnum.WAREHOUSE,
- row.code,
- row.name,
- );
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- formOptions: {
- schema: useGridFormSchema(),
- },
- gridOptions: {
- columns: useGridColumns(),
- height: 'auto',
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }, formValues) => {
- return await getWarehousePage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- ...formValues,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- search: true,
- },
- } as VxeTableGridOptions<MesWmWarehouseApi.Warehouse>,
-});
-</script>
-
-<template>
- <Page auto-content-height><FormModal @success="handleRefresh" />
- <BarcodeDetail ref="barcodeDetailRef" />
-
- <Grid table-title="浠撳簱鍒楄〃">
- <template #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: $t('ui.actionTitle.create', ['浠撳簱']),
- type: 'primary',
- icon: ACTION_ICON.ADD,
- auth: ['mes:wm-warehouse:create'],
- onClick: handleCreate,
- },
- ]"
- />
- </template>
- <template #code="{ row }">
- <Button type="link" @click="handleDetail(row)">
- {{ row.code }}
- </Button>
- </template>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: '搴撳尯',
- type: 'link',
- auth: ['mes:wm-warehouse:query'],
- onClick: handleOpenLocation.bind(null, row),
- },
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- auth: ['mes:wm-warehouse:update'],
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- auth: ['mes:wm-warehouse:delete'],
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.name]),
- confirm: handleDelete.bind(null, row),
- },
- },
- {
- label: '鏉$爜',
- type: 'link',
- auth: ['mes:wm-warehouse:query'],
- onClick: handleBarcode.bind(null, row),
- },
- ]"
- />
- </template>
- </Grid>
- </Page>
-</template>
diff --git a/src/views/warehouse/location/data.ts b/src/views/warehouse/location/data.ts
deleted file mode 100644
index 703c33e..0000000
--- a/src/views/warehouse/location/data.ts
+++ /dev/null
@@ -1,193 +0,0 @@
-import type { VbenFormApi, VbenFormSchema } from '#/adapter/form';
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmWarehouseApi } from '#/api/mes/wm/warehouse';
-import type { MesWmWarehouseLocationApi } from '#/api/mes/wm/warehouse/location';
-
-import { h } from 'vue';
-
-import { DICT_TYPE, MesAutoCodeRuleCode } from '@vben/constants';
-
-import { Button } from 'ant-design-vue';
-
-import { z } from '#/adapter/form';
-import { generateAutoCode } from '#/api/mes/md/autocode/record';
-import { getWarehouseSimpleList } from '#/api/mes/wm/warehouse';
-
-/** 琛ㄥ崟绫诲瀷 */
-export type FormType = 'create' | 'detail' | 'update';
-
-/** 鍏宠仈鏁版嵁 */
-let warehouseList: MesWmWarehouseApi.Warehouse[] = [];
-getWarehouseSimpleList().then((data) => (warehouseList = data));
-
-/** 鏂板/淇敼鐨勮〃鍗� */
-export function useFormSchema(
- formType: FormType,
- formApi?: VbenFormApi,
-): VbenFormSchema[] {
- return [
- {
- fieldName: 'id',
- component: 'Input',
- dependencies: { triggerFields: [''], show: () => false },
- },
- {
- fieldName: 'code',
- label: '搴撳尯缂栫爜',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ュ簱鍖虹紪鐮�',
- },
- rules: 'required',
- suffix:
- formType === 'detail'
- ? undefined
- : () =>
- h(
- Button,
- {
- type: 'default',
- onClick: async () => {
- const code = await generateAutoCode(
- MesAutoCodeRuleCode.WM_LOCATION_CODE,
- );
- await formApi?.setFieldValue('code', code);
- },
- },
- { default: () => '鑷姩鐢熸垚' },
- ),
- },
- {
- fieldName: 'name',
- label: '搴撳尯鍚嶇О',
- component: 'Input',
- componentProps: {
- placeholder: '璇疯緭鍏ュ簱鍖哄悕绉�',
- },
- rules: 'required',
- },
- {
- fieldName: 'warehouseId',
- label: '鎵�灞炰粨搴�',
- component: 'ApiSelect',
- componentProps: {
- allowClear: true,
- api: getWarehouseSimpleList,
- labelField: 'name',
- valueField: 'id',
- placeholder: '璇烽�夋嫨浠撳簱',
- },
- rules: 'required',
- },
- {
- fieldName: 'area',
- label: '闈㈢Н锛堛帯锛�',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0,
- precision: 2,
- placeholder: '璇疯緭鍏ラ潰绉�',
- },
- },
- {
- fieldName: 'frozen',
- label: '鏄惁鍐荤粨',
- component: 'Switch',
- componentProps: {
- checkedChildren: '鏄�',
- unCheckedChildren: '鍚�',
- },
- rules: z.boolean().default(false),
- },
- {
- fieldName: 'remark',
- label: '澶囨敞',
- component: 'Textarea',
- formItemClass: 'col-span-3',
- componentProps: {
- placeholder: '璇疯緭鍏ュ娉�',
- rows: 3,
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勬悳绱㈣〃鍗� */
-export function useGridFormSchema(): VbenFormSchema[] {
- return [
- {
- fieldName: 'code',
- label: '搴撳尯缂栫爜',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ュ簱鍖虹紪鐮�',
- },
- },
- {
- fieldName: 'name',
- label: '搴撳尯鍚嶇О',
- component: 'Input',
- componentProps: {
- allowClear: true,
- placeholder: '璇疯緭鍏ュ簱鍖哄悕绉�',
- },
- },
- ];
-}
-
-/** 鍒楄〃鐨勫瓧娈� */
-export function useGridColumns(): VxeTableGridOptions<MesWmWarehouseLocationApi.WarehouseLocation>['columns'] {
- return [
- {
- field: 'code',
- title: '搴撳尯缂栫爜',
- minWidth: 140,
- slots: { default: 'code' },
- },
- {
- field: 'name',
- title: '搴撳尯鍚嶇О',
- minWidth: 160,
- },
- {
- field: 'warehouseId',
- title: '鎵�灞炰粨搴�',
- minWidth: 140,
- formatter: ({ cellValue }) =>
- warehouseList.find((w) => w.id === cellValue)?.name ?? '',
- },
- {
- field: 'area',
- title: '闈㈢Н锛堛帯锛�',
- width: 110,
- },
- {
- field: 'frozen',
- title: '鍐荤粨',
- width: 90,
- cellRender: {
- name: 'CellDict',
- props: { type: DICT_TYPE.INFRA_BOOLEAN_STRING },
- },
- },
- {
- field: 'remark',
- title: '澶囨敞',
- minWidth: 180,
- },
- {
- field: 'createTime',
- title: '鍒涘缓鏃堕棿',
- width: 180,
- formatter: 'formatDateTime',
- },
- {
- title: '鎿嶄綔',
- width: 240,
- fixed: 'right',
- slots: { default: 'actions' },
- },
- ];
-}
diff --git a/src/views/warehouse/location/index.vue b/src/views/warehouse/location/index.vue
deleted file mode 100644
index d10fac8..0000000
--- a/src/views/warehouse/location/index.vue
+++ /dev/null
@@ -1,218 +0,0 @@
-<script lang="ts" setup>
-import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesWmWarehouseLocationApi } from '#/api/mes/wm/warehouse/location';
-
-import { ref } from 'vue';
-import { useRoute, useRouter } from 'vue-router';
-
-import { Page, useVbenModal } from '@vben/common-ui';
-import { BarcodeBizTypeEnum } from '@vben/constants';
-
-import { Alert, Button, message } from 'ant-design-vue';
-
-import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import { getWarehouse } from '#/api/mes/wm/warehouse';
-import {
- deleteWarehouseLocation,
- getWarehouseLocationPage,
-} from '#/api/mes/wm/warehouse/location';
-import { $t } from '#/locales';
-
-import { BarcodeDetail } from '../../barcode/components';
-import { useGridColumns, useGridFormSchema } from './data';
-import Form from './modules/form.vue';
-
-const route = useRoute();
-const router = useRouter();
-
-const [FormModal, formModalApi] = useVbenModal({
- connectedComponent: Form,
- destroyOnClose: true,
-});
-
-const barcodeDetailRef = ref<InstanceType<typeof BarcodeDetail>>();
-
-/** 褰撳墠浠撳簱涓婁笅鏂囷紙鍚屾浠� URL 瑙f瀽锛岀‘淇濋娆℃煡璇㈠甫寰椾笂 warehouseId锛� */
-const currentWarehouse = ref<{ id: number; name: string }>(
- (() => {
- const id = Number(route.query.warehouseId);
- return Number.isInteger(id) && id > 0
- ? { id, name: '' }
- : { id: 0, name: '' };
- })(),
-);
-
-/** 寮傛鍔犺浇浠撳簱鍚嶇О锛堜笉闃诲鍒楄〃鏌ヨ锛� */
-async function loadWarehouseName() {
- if (!currentWarehouse.value.id) {
- return;
- }
- try {
- const warehouse = await getWarehouse(currentWarehouse.value.id);
- currentWarehouse.value.name = warehouse.name || '';
- } catch {
- // 蹇界暐涓婄骇鍚嶇О鍔犺浇寮傚父锛屼笉褰卞搷鍒楄〃鏌ヨ
- }
-}
-loadWarehouseName();
-
-/** 鍒锋柊琛ㄦ牸 */
-function handleRefresh() {
- gridApi.query();
-}
-
-/** 鍒涘缓搴撳尯 */
-function handleCreate() {
- formModalApi
- .setData({
- formType: 'create',
- warehouseId: currentWarehouse.value.id || undefined,
- })
- .open();
-}
-
-/** 鏌ョ湅搴撳尯璇︽儏 */
-function handleDetail(row: MesWmWarehouseLocationApi.WarehouseLocation) {
- formModalApi.setData({ formType: 'detail', id: row.id }).open();
-}
-
-/** 缂栬緫搴撳尯 */
-function handleEdit(row: MesWmWarehouseLocationApi.WarehouseLocation) {
- formModalApi.setData({ formType: 'update', id: row.id }).open();
-}
-
-/** 鍒犻櫎搴撳尯 */
-async function handleDelete(row: MesWmWarehouseLocationApi.WarehouseLocation) {
- const hideLoading = message.loading({
- content: $t('ui.actionMessage.deleting', [row.name]),
- duration: 0,
- });
- try {
- await deleteWarehouseLocation(row.id!);
- message.success($t('ui.actionMessage.deleteSuccess', [row.name]));
- handleRefresh();
- } finally {
- hideLoading();
- }
-}
-
-/** 璺宠浆搴撲綅鍒楄〃 */
-function handleOpenArea(row: MesWmWarehouseLocationApi.WarehouseLocation) {
- router.push({
- name: 'MesWmArea',
- query: { locationId: String(row.id) },
- });
-}
-
-/** 鏌ョ湅搴撳尯鏉$爜 */
-function handleBarcode(row: MesWmWarehouseLocationApi.WarehouseLocation) {
- barcodeDetailRef.value?.openByBusiness(
- row.id!,
- BarcodeBizTypeEnum.LOCATION,
- row.code,
- row.name,
- );
-}
-
-const [Grid, gridApi] = useVbenVxeGrid({
- formOptions: {
- schema: useGridFormSchema(),
- },
- gridOptions: {
- columns: useGridColumns(),
- height: 'auto',
- keepSource: true,
- proxyConfig: {
- ajax: {
- query: async ({ page }, formValues) => {
- return await getWarehouseLocationPage({
- pageNo: page.currentPage,
- pageSize: page.pageSize,
- warehouseId: currentWarehouse.value.id || undefined,
- ...formValues,
- });
- },
- },
- },
- rowConfig: {
- keyField: 'id',
- isHover: true,
- },
- toolbarConfig: {
- refresh: true,
- search: true,
- },
- } as VxeTableGridOptions<MesWmWarehouseLocationApi.WarehouseLocation>,
-});
-</script>
-
-<template>
- <Page auto-content-height><FormModal @success="handleRefresh" />
- <BarcodeDetail ref="barcodeDetailRef" />
-
- <Alert
- v-if="currentWarehouse.id"
- class="mb-3"
- :message="`褰撳墠浠撳簱锛�${currentWarehouse.name || `#${currentWarehouse.id}`}`"
- show-icon
- type="info"
- />
-
- <Grid table-title="搴撳尯鍒楄〃">
- <template #toolbar-tools>
- <TableAction
- :actions="[
- {
- label: $t('ui.actionTitle.create', ['搴撳尯']),
- type: 'primary',
- icon: ACTION_ICON.ADD,
- auth: ['mes:wm-warehouse:create'],
- onClick: handleCreate,
- },
- ]"
- />
- </template>
- <template #code="{ row }">
- <Button type="link" @click="handleDetail(row)">
- {{ row.code }}
- </Button>
- </template>
- <template #actions="{ row }">
- <TableAction
- :actions="[
- {
- label: '搴撲綅',
- type: 'link',
- auth: ['mes:wm-warehouse:query'],
- onClick: handleOpenArea.bind(null, row),
- },
- {
- label: $t('common.edit'),
- type: 'link',
- icon: ACTION_ICON.EDIT,
- auth: ['mes:wm-warehouse:update'],
- onClick: handleEdit.bind(null, row),
- },
- {
- label: $t('common.delete'),
- type: 'link',
- danger: true,
- icon: ACTION_ICON.DELETE,
- auth: ['mes:wm-warehouse:delete'],
- popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.name]),
- confirm: handleDelete.bind(null, row),
- },
- },
- {
- label: '鏉$爜',
- type: 'link',
- auth: ['mes:wm-warehouse:query'],
- onClick: handleBarcode.bind(null, row),
- },
- ]"
- />
- </template>
- </Grid>
- </Page>
-</template>
diff --git a/src/views/warehouse/location/modules/form.vue b/src/views/warehouse/location/modules/form.vue
deleted file mode 100644
index 694c09e..0000000
--- a/src/views/warehouse/location/modules/form.vue
+++ /dev/null
@@ -1,184 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { MesWmWarehouseLocationApi } from '#/api/mes/wm/warehouse/location';
-
-import { computed, ref } from 'vue';
-
-import { confirm, useVbenModal } from '@vben/common-ui';
-import { BarcodeBizTypeEnum } from '@vben/constants';
-
-import { Button, message } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createWarehouseLocation,
- getWarehouseLocation,
- updateAreaByLocationId,
- updateWarehouseLocation,
-} from '#/api/mes/wm/warehouse/location';
-import { $t } from '#/locales';
-import { BarcodeDetail } from '#/views/wls/barcode/components';
-
-import { useFormSchema } from '../data';
-
-const emit = defineEmits(['success']);
-const formType = ref<FormType>('create');
-const formData = ref<MesWmWarehouseLocationApi.WarehouseLocation>();
-const barcodeDetailRef = ref<InstanceType<typeof BarcodeDetail>>();
-
-const getTitle = computed(() => {
- if (formType.value === 'detail') {
- return $t('ui.actionTitle.view', ['搴撳尯']);
- }
- return formType.value === 'update'
- ? $t('ui.actionTitle.edit', ['搴撳尯'])
- : $t('ui.actionTitle.create', ['搴撳尯']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 110,
- },
- wrapperClass: 'grid-cols-3',
- layout: 'horizontal',
- schema: [],
- showDefaultActions: false,
-});
-
-/** 鏌ョ湅鏉$爜 */
-function handleBarcode() {
- if (!formData.value?.id) {
- return;
- }
- barcodeDetailRef.value?.openByBusiness(
- formData.value.id,
- BarcodeBizTypeEnum.LOCATION,
- formData.value.code,
- formData.value.name,
- );
-}
-
-/** 鎵归噺璁剧疆搴撲綅娣锋斁瑙勫垯 */
-async function setMixingRule(type: 'batch' | 'item', allow: boolean) {
- if (!formData.value?.id) {
- return;
- }
- const text = type === 'item' ? '浜у搧娣锋斁' : '鎵规娣锋斁';
- try {
- await confirm(`纭瑕侀噸缃簱鍖轰笅鎵�鏈夊簱浣嶇殑${text}瑙勫垯鍚楋紵`);
- } catch {
- return;
- }
- await updateAreaByLocationId(
- formData.value.id,
- type === 'item' ? allow : undefined,
- type === 'batch' ? allow : undefined,
- );
- message.success('璁剧疆鎴愬姛');
-}
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- if (formType.value === 'detail') {
- await modalApi.close();
- return;
- }
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data =
- (await formApi.getValues()) as MesWmWarehouseLocationApi.WarehouseLocation;
- try {
- await (formData.value?.id
- ? updateWarehouseLocation(data)
- : createWarehouseLocation(data));
- // 鍏抽棴骞舵彁绀�
- await modalApi.close();
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- return;
- }
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{
- formType: FormType;
- id?: number;
- warehouseId?: number;
- }>();
- formType.value = data.formType;
- formApi.setState({ schema: useFormSchema(formType.value, formApi) });
- formApi.setDisabled(formType.value === 'detail');
- modalApi.setState({ showConfirmButton: formType.value !== 'detail' });
- if (data?.id) {
- modalApi.lock();
- try {
- formData.value = await getWarehouseLocation(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- return;
- }
- if (data?.warehouseId) {
- await formApi.setFieldValue('warehouseId', data.warehouseId);
- }
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- <div
- v-if="formType === 'update' && formData?.id"
- class="mx-4 mt-2 border-t pt-4"
- >
- <div class="mb-2 font-medium">搴撲綅娣锋斁瑙勫垯锛堟壒閲忚缃級</div>
- <div class="flex flex-wrap items-center gap-3">
- <span class="w-20">浜у搧娣锋斁</span>
- <Button
- size="small"
- type="primary"
- @click="setMixingRule('item', true)"
- >
- 鍏佽
- </Button>
- <Button size="small" danger @click="setMixingRule('item', false)">
- 涓嶅厑璁�
- </Button>
- </div>
- <div class="mt-2 flex flex-wrap items-center gap-3">
- <span class="w-20">鎵规娣锋斁</span>
- <Button
- size="small"
- type="primary"
- @click="setMixingRule('batch', true)"
- >
- 鍏佽
- </Button>
- <Button size="small" danger @click="setMixingRule('batch', false)">
- 涓嶅厑璁�
- </Button>
- </div>
- </div>
- <template v-if="formType === 'detail' && formData?.id" #prepend-footer>
- <Button @click="handleBarcode"> 鏌ョ湅鏉$爜 </Button>
- </template>
- <BarcodeDetail ref="barcodeDetailRef" />
- </Modal>
-</template>
diff --git a/src/views/warehouse/modules/form.vue b/src/views/warehouse/modules/form.vue
deleted file mode 100644
index f545f35..0000000
--- a/src/views/warehouse/modules/form.vue
+++ /dev/null
@@ -1,124 +0,0 @@
-<script lang="ts" setup>
-import type { FormType } from '../data';
-
-import type { MesWmWarehouseApi } from '#/api/mes/wm/warehouse';
-
-import { computed, ref } from 'vue';
-
-import { useVbenModal } from '@vben/common-ui';
-import { BarcodeBizTypeEnum } from '@vben/constants';
-
-import { Button, message } from 'ant-design-vue';
-
-import { useVbenForm } from '#/adapter/form';
-import {
- createWarehouse,
- getWarehouse,
- updateWarehouse,
-} from '#/api/mes/wm/warehouse';
-import { $t } from '#/locales';
-import { BarcodeDetail } from '#/views/wls/barcode/components';
-
-import { useFormSchema } from '../data';
-
-const emit = defineEmits(['success']);
-const formType = ref<FormType>('create');
-const formData = ref<MesWmWarehouseApi.Warehouse>();
-const barcodeDetailRef = ref<InstanceType<typeof BarcodeDetail>>();
-
-const getTitle = computed(() => {
- if (formType.value === 'detail') {
- return $t('ui.actionTitle.view', ['浠撳簱']);
- }
- return formType.value === 'update'
- ? $t('ui.actionTitle.edit', ['浠撳簱'])
- : $t('ui.actionTitle.create', ['浠撳簱']);
-});
-
-const [Form, formApi] = useVbenForm({
- commonConfig: {
- componentProps: {
- class: 'w-full',
- },
- formItemClass: 'col-span-1',
- labelWidth: 110,
- },
- wrapperClass: 'grid-cols-3',
- layout: 'horizontal',
- schema: [],
- showDefaultActions: false,
-});
-
-/** 鏌ョ湅鏉$爜 */
-function handleBarcode() {
- if (!formData.value?.id) {
- return;
- }
- barcodeDetailRef.value?.openByBusiness(
- formData.value.id,
- BarcodeBizTypeEnum.WAREHOUSE,
- formData.value.code,
- formData.value.name,
- );
-}
-
-const [Modal, modalApi] = useVbenModal({
- async onConfirm() {
- if (formType.value === 'detail') {
- await modalApi.close();
- return;
- }
- const { valid } = await formApi.validate();
- if (!valid) {
- return;
- }
- modalApi.lock();
- // 鎻愪氦琛ㄥ崟
- const data = (await formApi.getValues()) as MesWmWarehouseApi.Warehouse;
- try {
- await (formData.value?.id
- ? updateWarehouse(data)
- : createWarehouse(data));
- // 鍏抽棴骞舵彁绀�
- await modalApi.close();
- emit('success');
- message.success($t('ui.actionMessage.operationSuccess'));
- } finally {
- modalApi.unlock();
- }
- },
- async onOpenChange(isOpen: boolean) {
- if (!isOpen) {
- formData.value = undefined;
- return;
- }
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{ formType: FormType; id?: number }>();
- formType.value = data.formType;
- formApi.setState({ schema: useFormSchema(formType.value, formApi) });
- formApi.setDisabled(formType.value === 'detail');
- modalApi.setState({ showConfirmButton: formType.value !== 'detail' });
- if (!data?.id) {
- return;
- }
- modalApi.lock();
- try {
- formData.value = await getWarehouse(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value);
- } finally {
- modalApi.unlock();
- }
- },
-});
-</script>
-
-<template>
- <Modal :title="getTitle" class="w-3/5">
- <Form class="mx-4" />
- <template v-if="formType === 'detail' && formData?.id" #prepend-footer>
- <Button @click="handleBarcode"> 鏌ョ湅鏉$爜 </Button>
- </template>
- <BarcodeDetail ref="barcodeDetailRef" />
- </Modal>
-</template>
diff --git a/src/views/wls/batch/components/detail.vue b/src/views/wls/batch/components/detail.vue
index 2f0dff0..db02e8a 100644
--- a/src/views/wls/batch/components/detail.vue
+++ b/src/views/wls/batch/components/detail.vue
@@ -1,18 +1,58 @@
<script lang="ts" setup>
+import type { MdmItemApi } from '#/api/mdm/item';
import type { MesWmBatchApi } from '#/api/mes/wm/batch';
+import type { DescriptionItemSchema } from '#/components/description';
import { ref } from 'vue';
import { useVbenModal } from '@vben/common-ui';
+import { getItem } from '#/api/mdm/item';
import { getBatch } from '#/api/mes/wm/batch';
import { useDescription } from '#/components/description';
import { useDetailSchema } from '../data';
-const detailData = ref<MesWmBatchApi.Batch>(); // 褰撳墠鎵规璇︽儏
+const detailData = ref<MesWmBatchApi.Batch>();
+const itemData = ref<MdmItemApi.Item>();
-const [Descriptions] = useDescription({
+/** 鏍规嵁鐗╂枡鎵规灞炴�ч厤缃繃婊よ鎯呭瓧娈� */
+function filterSchemaByItemFlags(
+ schema: DescriptionItemSchema[],
+ item: MdmItemApi.Item | undefined,
+): DescriptionItemSchema[] {
+ // 鍩虹鏁版嵁瀛楁濮嬬粓鏄剧ず
+ const basicFields = new Set([
+ 'code',
+ 'itemCode',
+ 'itemName',
+ 'itemSpecification',
+ 'unitName',
+ ]);
+
+ // 鎵规灞炴�у瓧娈典笌 flag 鐨勬槧灏�
+ const flagFieldMap: Record<string, keyof MdmItemApi.Item> = {
+ produceDate: 'produceDateFlag',
+ expireDate: 'expireDateFlag',
+ receiptDate: 'receiptDateFlag',
+ vendorName: 'vendorFlag',
+ purchaseOrderCode: 'purchaseOrderCodeFlag',
+ lotNumber: 'lotNumberFlag',
+ qualityStatus: 'qualityStatusFlag',
+ };
+
+ return schema.filter((s) => {
+ if (basicFields.has(s.field!)) return true;
+ const flagField = flagFieldMap[s.field!];
+ if (flagField) {
+ return item?.[flagField] === true;
+ }
+ // 闈炲熀纭�銆侀潪鎵规灞炴�у瓧娈典笉灞曠ず
+ return false;
+ });
+}
+
+const [Descriptions, descApi] = useDescription({
bordered: true,
column: 3,
schema: useDetailSchema(),
@@ -25,6 +65,7 @@
async onOpenChange(isOpen) {
if (!isOpen) {
detailData.value = undefined;
+ itemData.value = undefined;
return;
}
const data = modalApi.getData<{ id?: number }>();
@@ -34,6 +75,15 @@
modalApi.lock();
try {
detailData.value = await getBatch(data.id);
+ // 鑾峰彇鐗╂枡璇︽儏浠ヨ鍙栨壒娆″睘鎬ч厤缃�
+ if (detailData.value?.itemId) {
+ itemData.value = await getItem(detailData.value.itemId);
+ const filtered = filterSchemaByItemFlags(
+ useDetailSchema(),
+ itemData.value,
+ );
+ descApi.setDescProps({ schema: filtered });
+ }
} finally {
modalApi.unlock();
}
diff --git a/src/views/wls/itemreceipt/data.ts b/src/views/wls/itemreceipt/data.ts
index 4864dc2..135042d 100644
--- a/src/views/wls/itemreceipt/data.ts
+++ b/src/views/wls/itemreceipt/data.ts
@@ -19,7 +19,7 @@
import { generateAutoCode } from '#/api/mes/md/autocode/record';
import { getRangePickerDefaultProps } from '#/utils';
import { MdItemSelect } from '#/views/mes/md/item/components';
-import { MdVendorSelect } from '#/views/mes/md/vendor/components';
+import { ErpSupplierSelect } from '#/views/erp/purchase/supplier/components';
import {
WmArrivalNoticeLineSelect,
WmArrivalNoticeSelect,
@@ -123,7 +123,7 @@
{
fieldName: 'vendorId',
label: '渚涘簲鍟�',
- component: markRaw(MdVendorSelect),
+ component: markRaw(ErpSupplierSelect),
componentProps: {
placeholder: '璇烽�夋嫨渚涘簲鍟�',
},
@@ -174,7 +174,7 @@
{
fieldName: 'vendorId',
label: '渚涘簲鍟�',
- component: markRaw(MdVendorSelect),
+ component: markRaw(ErpSupplierSelect),
componentProps: {
placeholder: '璇烽�夋嫨渚涘簲鍟�',
},
diff --git a/src/views/wls/materialstock/components/batch-config-display.vue b/src/views/wls/materialstock/components/batch-config-display.vue
index ff4c52b..01a4cf0 100644
--- a/src/views/wls/materialstock/components/batch-config-display.vue
+++ b/src/views/wls/materialstock/components/batch-config-display.vue
@@ -1,92 +1,41 @@
<script lang="ts" setup>
-import type { MdmItemBatchConfigApi } from '#/api/mes/md/item-batch-config';
+import type { MdmItemApi } from '#/api/mdm/item';
-import { computed, ref, watch } from 'vue';
+import { computed } from 'vue';
import { Divider, Tag } from 'ant-design-vue';
-import { getItemBatchConfigByItemId } from '#/api/mes/md/item-batch-config';
-
const props = defineProps<{
- itemId?: number;
- isBatchManaged?: boolean;
+ item?: MdmItemApi.Item | null;
}>();
-// 鎵规閰嶇疆鏁版嵁
-const config = ref<MdmItemBatchConfigApi.ItemBatchConfig | null>(null);
-
-// 鏄惁鍔犺浇涓�
-const loading = ref(false);
-
// 鏄惁鏄剧ず锛堝惎鐢ㄦ壒娆$鐞嗘椂鏄剧ず锛�
-const visible = computed(() => props.isBatchManaged === true);
+const visible = computed(() => props.item?.isBatchManaged === true);
-// 宸插惎鐢ㄧ殑鎵规灞炴�у垪琛紙浠呬繚鐣�7涓瓧娈碉級
+// 宸插惎鐢ㄧ殑鎵规灞炴�у垪琛�
const enabledProps = computed(() => {
- if (!config.value) return [];
- const props: { label: string; value: boolean }[] = [];
- if (config.value.produceDateFlag) props.push({ label: '鐢熶骇鏃ユ湡', value: true });
- if (config.value.expireDateFlag) props.push({ label: '鏈夋晥鏈�', value: true });
- if (config.value.receiptDateFlag) props.push({ label: '鍏ュ簱鏃ユ湡', value: true });
- if (config.value.vendorFlag) props.push({ label: '渚涘簲鍟�', value: true });
- if (config.value.purchaseOrderCodeFlag) props.push({ label: '閲囪喘璁㈠崟鍙�', value: true });
- if (config.value.lotNumberFlag) props.push({ label: '鐢熶骇鎵瑰彿', value: true });
- if (config.value.qualityStatusFlag) props.push({ label: '璐ㄩ噺鐘舵��', value: true });
- return props;
-});
-
-/** 鍔犺浇鎵规閰嶇疆 */
-async function loadConfig() {
- if (!props.itemId || !props.isBatchManaged) {
- config.value = null;
- return;
- }
- loading.value = true;
- try {
- const data = await getItemBatchConfigByItemId(props.itemId);
- config.value = data;
- } catch {
- config.value = null;
- } finally {
- loading.value = false;
- }
-}
-
-/** 閲嶇疆 */
-function reset() {
- config.value = null;
- loading.value = false;
-}
-
-// 鐩戝惉 itemId 鍙樺寲锛屽姞杞介厤缃�
-watch(
- () => [props.itemId, props.isBatchManaged],
- () => {
- if (props.itemId && props.isBatchManaged) {
- loadConfig();
- } else {
- reset();
- }
- },
- { immediate: true },
-);
-
-defineExpose({
- loadConfig,
- reset,
+ if (!props.item) return [];
+ const list: string[] = [];
+ if (props.item.produceDateFlag) list.push('鐢熶骇鏃ユ湡');
+ if (props.item.expireDateFlag) list.push('鏈夋晥鏈�');
+ if (props.item.receiptDateFlag) list.push('鍏ュ簱鏃ユ湡');
+ if (props.item.vendorFlag) list.push('渚涘簲鍟�');
+ if (props.item.purchaseOrderCodeFlag) list.push('閲囪喘璁㈠崟鍙�');
+ if (props.item.lotNumberFlag) list.push('鐢熶骇鎵瑰彿');
+ if (props.item.qualityStatusFlag) list.push('璐ㄩ噺鐘舵��');
+ return list;
});
</script>
<template>
- <div v-if="visible" class="mt-4 rounded border border-gray-200 bg-gray-50 p-4">
+ <div v-if="visible" class="mx-4 mt-4 rounded border border-gray-200 bg-gray-50 p-4">
<Divider orientation="left">鎵规灞炴��</Divider>
- <div v-if="loading" class="text-center text-gray-500">鍔犺浇涓�...</div>
- <div v-else-if="enabledProps.length === 0" class="text-center text-gray-500">
+ <div v-if="enabledProps.length === 0" class="text-center text-gray-500">
璇ョ墿鏂欐湭閰嶇疆鎵规灞炴��
</div>
<div v-else class="flex flex-wrap gap-2">
- <Tag v-for="prop in enabledProps" :key="prop.label" color="blue">
- {{ prop.label }}
+ <Tag v-for="prop in enabledProps" :key="prop" color="blue">
+ {{ prop }}
</Tag>
</div>
<p class="mt-2 text-xs text-gray-500">
diff --git a/src/views/wls/materialstock/components/stock-adjust-modal.vue b/src/views/wls/materialstock/components/stock-adjust-modal.vue
index 31f31e9..aeb5883 100644
--- a/src/views/wls/materialstock/components/stock-adjust-modal.vue
+++ b/src/views/wls/materialstock/components/stock-adjust-modal.vue
@@ -4,7 +4,6 @@
MaterialStockAdjustOutParams,
} from '#/api/mes/wm/materialstock';
import type { MdmItemApi } from '#/api/mdm/item';
-import type { MdmItemBatchConfigApi } from '#/api/mes/md/item-batch-config';
import type { VbenFormSchema } from '#/adapter/form';
import { ref } from 'vue';
@@ -20,9 +19,8 @@
adjustMaterialStockOut,
} from '#/api/mes/wm/materialstock';
import { getItem } from '#/api/mdm/item';
-import { getItemBatchConfigByItemId } from '#/api/mes/md/item-batch-config';
import { MdmItemSelect } from '#/views/basicData/mdm/components';
-import { MdVendorSelect } from '#/views/mes/md/vendor/components';
+import { ErpSupplierSelect } from '#/views/erp/purchase/supplier/components';
import BatchConfigDisplay from './batch-config-display.vue';
import {
WmWarehouseAreaSelect,
@@ -44,56 +42,45 @@
const batchEnabled = ref(false);
// 鏄惁鎵嬪姩濉啓鎵规鍙�
const manualBatchEntry = ref(false);
-// 鐗╂枡鎵规閰嶇疆
-const batchConfig = ref<MdmItemBatchConfigApi.ItemBatchConfig | null>(null);
// 鎵规閰嶇疆灞曠ず缁勪欢寮曠敤
const batchConfigDisplayRef = ref<InstanceType<typeof BatchConfigDisplay>>();
// 鏍囬
const modalTitle = ref('搴撳瓨璋冩暣');
-/** 鍔犺浇鐗╂枡鎵规閰嶇疆骞舵洿鏂板瓧娈垫樉绀� */
-async function loadBatchConfigAndUpdateFields(itemId: number) {
- try {
- const config = await getItemBatchConfigByItemId(itemId);
- batchConfig.value = config;
- } catch {
- batchConfig.value = null;
- }
- await updateBatchFields();
-}
-
-/** 鏇存柊鎵规瀛楁鏄剧ず锛堟牴鎹厤缃睍绀哄凡鍚敤鐨勫睘鎬э級 */
+/** 鏇存柊鎵规瀛楁鏄剧ず锛堟牴鎹墿鏂欐暟鎹腑鐨勬壒娆¢厤缃睍绀哄凡鍚敤鐨勫睘鎬э級 */
async function updateBatchFields() {
const enabled = selectedItem.value?.isBatchManaged === true;
batchEnabled.value = enabled;
if (!enabled) {
- // 闅愯棌鎵�鏈夋壒娆$浉鍏冲瓧娈�
formApi.updateSchema([
{ fieldName: 'batchCode', dependencies: { show: () => false } },
+ { fieldName: 'manualBatchEntry', dependencies: { show: () => false } },
{ fieldName: 'produceDate', dependencies: { show: () => false } },
{ fieldName: 'expireDate', dependencies: { show: () => false } },
- { fieldName: 'manualBatchEntry', dependencies: { show: () => false } },
+ { fieldName: 'receiptDate', dependencies: { show: () => false } },
{ fieldName: 'vendorId', dependencies: { show: () => true } },
+ { fieldName: 'purchaseOrderCode', dependencies: { show: () => false } },
+ { fieldName: 'lotNumber', dependencies: { show: () => false } },
+ { fieldName: 'qualityStatus', dependencies: { show: () => false } },
]);
return;
}
- // 鍚敤鎵规绠$悊锛屾牴鎹厤缃樉绀哄瓧娈�
- const config = batchConfig.value;
+ const item = selectedItem.value;
const isIn = operateType.value === 1;
- // 鏄惁鎵嬪姩濉啓鎵规鍙锋帶鍒舵壒娆″彿瀛楁鐨勬樉绀�
- const showBatchCode = manualBatchEntry.value;
- const showProduceDate = isIn && !!config?.produceDateFlag;
- const showExpireDate = isIn && !!config?.expireDateFlag;
-
formApi.updateSchema([
- { fieldName: 'batchCode', dependencies: { show: () => showBatchCode } },
- { fieldName: 'produceDate', dependencies: { show: () => showProduceDate } },
- { fieldName: 'expireDate', dependencies: { show: () => showExpireDate } },
+ { fieldName: 'batchCode', dependencies: { show: () => manualBatchEntry.value } },
{ fieldName: 'manualBatchEntry', dependencies: { show: () => true } },
+ { fieldName: 'produceDate', dependencies: { show: () => isIn && !!item?.produceDateFlag } },
+ { fieldName: 'expireDate', dependencies: { show: () => isIn && !!item?.expireDateFlag } },
+ { fieldName: 'receiptDate', dependencies: { show: () => isIn && !!item?.receiptDateFlag } },
+ { fieldName: 'vendorId', dependencies: { show: () => !isIn || !!item?.vendorFlag } },
+ { fieldName: 'purchaseOrderCode', dependencies: { show: () => isIn && !!item?.purchaseOrderCodeFlag } },
+ { fieldName: 'lotNumber', dependencies: { show: () => isIn && !!item?.lotNumberFlag } },
+ { fieldName: 'qualityStatus', dependencies: { show: () => isIn && !!item?.qualityStatusFlag } },
]);
}
@@ -103,10 +90,9 @@
if (item?.id) {
const itemDetail = await getItem(item.id);
selectedItem.value = itemDetail;
- // 鍔犺浇鐗╂枡鎵规閰嶇疆骞舵洿鏂板瓧娈�
- await loadBatchConfigAndUpdateFields(item.id);
+ // 鏍规嵁鐗╂枡鏁版嵁鏇存柊鎵规瀛楁
+ await updateBatchFields();
} else {
- batchConfig.value = null;
batchEnabled.value = false;
}
// 娓呯┖鎵规鐩稿叧鍊�
@@ -290,17 +276,77 @@
},
dependencies: {
triggerFields: ['itemId'],
- show: () => false, // 榛樿闅愯棌
+ show: () => false,
+ },
+ },
+ // 鍏ュ簱鏃ユ湡锛堟牴鎹壒娆¢厤缃樉绀猴紝浠呭叆搴擄級
+ {
+ fieldName: 'receiptDate',
+ label: '鍏ュ簱鏃ユ湡',
+ component: 'DatePicker',
+ componentProps: {
+ placeholder: '璇烽�夋嫨鍏ュ簱鏃ユ湡',
+ format: 'YYYY-MM-DD',
+ valueFormat: 'YYYY-MM-DD',
+ },
+ dependencies: {
+ triggerFields: ['itemId'],
+ show: () => false,
},
},
{
fieldName: 'vendorId',
label: '渚涘簲鍟�',
- component: markRaw(MdVendorSelect),
+ component: markRaw(ErpSupplierSelect),
componentProps: {
placeholder: '璇烽�夋嫨渚涘簲鍟�',
},
rules: 'selectRequired',
+ },
+ // 閲囪喘璁㈠崟鍙凤紙鏍规嵁鎵规閰嶇疆鏄剧ず锛屼粎鍏ュ簱锛�
+ {
+ fieldName: 'purchaseOrderCode',
+ label: '閲囪喘璁㈠崟鍙�',
+ component: 'Input',
+ componentProps: {
+ placeholder: '璇疯緭鍏ラ噰璐鍗曞彿',
+ },
+ dependencies: {
+ triggerFields: ['itemId'],
+ show: () => false,
+ },
+ },
+ // 鐢熶骇鎵瑰彿锛堟牴鎹壒娆¢厤缃樉绀猴紝浠呭叆搴擄級
+ {
+ fieldName: 'lotNumber',
+ label: '鐢熶骇鎵瑰彿',
+ component: 'Input',
+ componentProps: {
+ placeholder: '璇疯緭鍏ョ敓浜ф壒鍙�',
+ },
+ dependencies: {
+ triggerFields: ['itemId'],
+ show: () => false,
+ },
+ },
+ // 璐ㄩ噺鐘舵�侊紙鏍规嵁鎵规閰嶇疆鏄剧ず锛屼粎鍏ュ簱锛�
+ {
+ fieldName: 'qualityStatus',
+ label: '璐ㄩ噺鐘舵��',
+ component: 'Select',
+ componentProps: {
+ placeholder: '璇烽�夋嫨璐ㄩ噺鐘舵��',
+ allowClear: true,
+ options: [
+ { label: '鍚堟牸', value: 'QUALIFIED' },
+ { label: '涓嶅悎鏍�', value: 'UNQUALIFIED' },
+ { label: '寰呮', value: 'PENDING' },
+ ],
+ },
+ dependencies: {
+ triggerFields: ['itemId'],
+ show: () => false,
+ },
},
{
fieldName: 'quantity',
@@ -355,7 +401,6 @@
selectedWarehouse.value = null;
selectedLocation.value = null;
batchEnabled.value = false;
- batchConfig.value = null;
operateType.value = 1;
modalTitle.value = '搴撳瓨璋冩暣';
return;
@@ -365,9 +410,13 @@
// 榛樿闅愯棌鎵规鐩稿叧瀛楁
formApi.updateSchema([
{ fieldName: 'batchCode', dependencies: { show: () => false } },
+ { fieldName: 'manualBatchEntry', dependencies: { show: () => false } },
{ fieldName: 'produceDate', dependencies: { show: () => false } },
{ fieldName: 'expireDate', dependencies: { show: () => false } },
- { fieldName: 'manualBatchEntry', dependencies: { show: () => false } },
+ { fieldName: 'receiptDate', dependencies: { show: () => false } },
+ { fieldName: 'purchaseOrderCode', dependencies: { show: () => false } },
+ { fieldName: 'lotNumber', dependencies: { show: () => false } },
+ { fieldName: 'qualityStatus', dependencies: { show: () => false } },
]);
// 閲嶇疆鎵嬪姩濉啓鎵规鍙风姸鎬�
manualBatchEntry.value = false;
@@ -383,7 +432,7 @@
if (data.itemId) {
const itemDetail = await getItem(data.itemId);
selectedItem.value = itemDetail;
- await loadBatchConfigAndUpdateFields(data.itemId);
+ await updateBatchFields();
}
}
},
@@ -399,35 +448,36 @@
const values = await formApi.getValues();
- const {
- itemId,
- warehouseId,
- locationId,
- areaId,
- batchCode,
- produceDate,
- expireDate,
- vendorId,
- quantity,
- reason,
- } = values;
-
// 鍚敤鎵规绠$悊鏃剁殑鏍¢獙
if (batchEnabled.value) {
- // 鎵嬪姩濉啓鎵规鍙锋椂锛屾壒娆″彿蹇呭~
- if (manualBatchEntry.value && !batchCode) {
+ if (manualBatchEntry.value && !values.batchCode) {
message.error('璇疯緭鍏ユ壒娆″彿');
return;
}
- // 鏍规嵁鎵规閰嶇疆鏍¢獙蹇呭~瀛楁锛堜粎鍏ュ簱锛�
if (operateType.value === 1) {
- const config = batchConfig.value;
- if (config?.produceDateFlag && !produceDate) {
+ const item = selectedItem.value;
+ if (item?.produceDateFlag && !values.produceDate) {
message.error('璇烽�夋嫨鐢熶骇鏃ユ湡');
return;
}
- if (config?.expireDateFlag && !expireDate) {
+ if (item?.expireDateFlag && !values.expireDate) {
message.error('璇烽�夋嫨鏈夋晥鏈�');
+ return;
+ }
+ if (item?.receiptDateFlag && !values.receiptDate) {
+ message.error('璇烽�夋嫨鍏ュ簱鏃ユ湡');
+ return;
+ }
+ if (item?.purchaseOrderCodeFlag && !values.purchaseOrderCode) {
+ message.error('璇疯緭鍏ラ噰璐鍗曞彿');
+ return;
+ }
+ if (item?.lotNumberFlag && !values.lotNumber) {
+ message.error('璇疯緭鍏ョ敓浜ф壒鍙�');
+ return;
+ }
+ if (item?.qualityStatusFlag && !values.qualityStatus) {
+ message.error('璇烽�夋嫨璐ㄩ噺鐘舵��');
return;
}
}
@@ -439,30 +489,34 @@
if (type === 1) {
// 鍏ュ簱
const params: MaterialStockAdjustInParams = {
- itemId,
- warehouseId,
- locationId,
- areaId,
- batchCode,
- produceDate,
- expireDate,
- vendorId,
- quantity,
- reason,
+ itemId: values.itemId,
+ warehouseId: values.warehouseId,
+ locationId: values.locationId,
+ areaId: values.areaId,
+ batchCode: values.batchCode,
+ produceDate: values.produceDate,
+ expireDate: values.expireDate,
+ receiptDate: values.receiptDate,
+ vendorId: values.vendorId,
+ purchaseOrderCode: values.purchaseOrderCode,
+ lotNumber: values.lotNumber,
+ qualityStatus: values.qualityStatus,
+ quantity: values.quantity,
+ reason: values.reason,
};
await adjustMaterialStockIn(params);
message.success('鍏ュ簱鎴愬姛');
} else {
// 鍑哄簱
const params: MaterialStockAdjustOutParams = {
- itemId,
- warehouseId,
- locationId,
- areaId,
- batchCode,
- vendorId,
- quantity,
- reason,
+ itemId: values.itemId,
+ warehouseId: values.warehouseId,
+ locationId: values.locationId,
+ areaId: values.areaId,
+ batchCode: values.batchCode,
+ vendorId: values.vendorId,
+ quantity: values.quantity,
+ reason: values.reason,
};
await adjustMaterialStockOut(params);
message.success('鍑哄簱鎴愬姛');
@@ -481,8 +535,7 @@
<Form class="mx-4" />
<BatchConfigDisplay
ref="batchConfigDisplayRef"
- :item-id="selectedItem?.id"
- :is-batch-managed="batchEnabled"
+ :item="selectedItem"
/>
</Modal>
</template>
diff --git a/vite.config.ts b/vite.config.ts
index fc2ee92..5a07335 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -42,7 +42,7 @@
"/admin-api": {
changeOrigin: true,
rewrite: path => path.replace(/^\/admin-api/, ""),
- target: "http://192.168.0.244:48080/admin-api",
+ target: "http://192.168.0.226:48080/admin-api",
ws: true,
},
},
--
Gitblit v1.9.3