<script lang="ts" setup>
|
import type { ErpPurchasePlanApi } from '#/api/erp/purchase/plan';
|
|
import { computed, ref } from 'vue';
|
|
import { useVbenModal } from '@vben/common-ui';
|
|
import { Button, DatePicker, Input, InputNumber, message } from 'ant-design-vue';
|
|
import { useVbenForm } from '#/adapter/form';
|
import {
|
createPurchasePlan,
|
getPurchasePlan,
|
updatePurchasePlan,
|
} from '#/api/erp/purchase/plan';
|
import { MdmItemSelect } from '#/views/basicData/mdm/components';
|
import { $t } from '#/locales';
|
|
import type { FormType } from '../data';
|
import { useFormSchema } from '../data';
|
|
const emit = defineEmits(['success']);
|
const formData = ref<ErpPurchasePlanApi.PurchasePlan>();
|
const formType = ref<FormType>('create');
|
const items = ref<ErpPurchasePlanApi.PurchasePlanItem[]>([]);
|
|
const getTitle = computed(() => {
|
if (formType.value === 'create') {
|
return $t('ui.actionTitle.create', ['采购计划']);
|
} else if (formType.value === 'edit') {
|
return $t('ui.actionTitle.edit', ['采购计划']);
|
} else {
|
return '采购计划详情';
|
}
|
});
|
|
const [Form, formApi] = useVbenForm({
|
commonConfig: {
|
componentProps: {
|
class: 'w-full',
|
},
|
labelWidth: 120,
|
},
|
wrapperClass: 'grid-cols-3',
|
layout: 'vertical',
|
schema: useFormSchema(formType.value),
|
showDefaultActions: false,
|
});
|
|
function handleAddItem() {
|
items.value.push({
|
productId: undefined as unknown as number,
|
productName: '',
|
productUnitId: undefined as unknown as number,
|
productUnitName: '',
|
count: 1,
|
demandTime: undefined,
|
remark: '',
|
});
|
}
|
|
function handleRemoveItem(index: number) {
|
items.value.splice(index, 1);
|
}
|
|
function handleItemSelect(index: number, item: any) {
|
const row = items.value[index];
|
if (!row) {
|
return;
|
}
|
row.productId = item?.id;
|
row.productName = item?.name;
|
row.productUnitId = item?.unitMeasureId;
|
row.productUnitName = item?.unitMeasureName;
|
}
|
|
/** 创建或更新采购计划 */
|
const [Modal, modalApi] = useVbenModal({
|
async onConfirm() {
|
const { valid } = await formApi.validate();
|
if (!valid) {
|
return;
|
}
|
if (!items.value.length) {
|
message.error('请至少添加一条计划明细');
|
return;
|
}
|
if (items.value.some((item) => !item.productId || !item.count)) {
|
message.error('请完善计划明细的产品与数量');
|
return;
|
}
|
modalApi.lock();
|
const data =
|
(await formApi.getValues()) as ErpPurchasePlanApi.PurchasePlan;
|
data.items = items.value.map((item) => ({
|
productId: item.productId,
|
productUnitId: item.productUnitId,
|
count: item.count,
|
demandTime: item.demandTime,
|
remark: item.remark,
|
}));
|
try {
|
await (formType.value === 'create'
|
? createPurchasePlan(data)
|
: updatePurchasePlan(data));
|
await modalApi.close();
|
emit('success');
|
message.success($t('ui.actionMessage.operationSuccess'));
|
} finally {
|
modalApi.unlock();
|
}
|
},
|
async onOpenChange(isOpen: boolean) {
|
if (!isOpen) {
|
formData.value = undefined;
|
items.value = [];
|
return;
|
}
|
const data = modalApi.getData<{ formType: FormType; id?: number }>();
|
formType.value = data.formType;
|
formApi.setDisabled(formType.value === 'detail');
|
formApi.updateSchema(useFormSchema(formType.value));
|
if (!data || !data.id) {
|
return;
|
}
|
modalApi.lock();
|
try {
|
formData.value = await getPurchasePlan(data.id);
|
await formApi.setValues(formData.value);
|
items.value = (formData.value.items ?? []).map((item) => ({
|
...item,
|
}));
|
} finally {
|
modalApi.unlock();
|
}
|
},
|
});
|
</script>
|
|
<template>
|
<Modal
|
:title="getTitle"
|
class="w-3/4"
|
:show-confirm-button="formType !== 'detail'"
|
>
|
<Form class="mx-3">
|
<template #items>
|
<div class="mt-2">
|
<div v-if="formType !== 'detail'" class="mb-2">
|
<Button type="dashed" @click="handleAddItem">+ 添加明细</Button>
|
</div>
|
<table class="w-full border-collapse border border-gray-200 text-sm">
|
<thead>
|
<tr class="bg-gray-100">
|
<th class="border border-gray-200 px-2 py-1 w-12">序号</th>
|
<th class="border border-gray-200 px-2 py-1">产品</th>
|
<th class="border border-gray-200 px-2 py-1 w-20">单位</th>
|
<th class="border border-gray-200 px-2 py-1 w-32">数量</th>
|
<th class="border border-gray-200 px-2 py-1 w-40">需求日期</th>
|
<th class="border border-gray-200 px-2 py-1">备注</th>
|
<th
|
v-if="formType !== 'detail'"
|
class="border border-gray-200 px-2 py-1 w-16"
|
>
|
操作
|
</th>
|
</tr>
|
</thead>
|
<tbody>
|
<tr v-for="(item, index) in items" :key="index">
|
<td class="border border-gray-200 px-2 py-1 text-center">
|
{{ index + 1 }}
|
</td>
|
<td class="border border-gray-200 px-2 py-1">
|
<MdmItemSelect
|
v-if="formType !== 'detail'"
|
:model-value="item.productId"
|
placeholder="请选择产品"
|
@change="handleItemSelect(index, $event)"
|
/>
|
<span v-else>{{ item.productName }}</span>
|
</td>
|
<td class="border border-gray-200 px-2 py-1 text-center">
|
{{ item.productUnitName || '-' }}
|
</td>
|
<td class="border border-gray-200 px-2 py-1">
|
<InputNumber
|
v-if="formType !== 'detail'"
|
v-model:value="item.count"
|
class="!w-full"
|
:min="0.01"
|
:precision="2"
|
/>
|
<span v-else>{{ item.count }}</span>
|
</td>
|
<td class="border border-gray-200 px-2 py-1">
|
<DatePicker
|
v-if="formType !== 'detail'"
|
v-model:value="item.demandTime"
|
class="!w-full"
|
value-format="YYYY-MM-DD"
|
/>
|
<span v-else>{{ item.demandTime || '-' }}</span>
|
</td>
|
<td class="border border-gray-200 px-2 py-1">
|
<Input
|
v-if="formType !== 'detail'"
|
v-model:value="item.remark"
|
placeholder="备注"
|
/>
|
<span v-else>{{ item.remark || '-' }}</span>
|
</td>
|
<td
|
v-if="formType !== 'detail'"
|
class="border border-gray-200 px-2 py-1 text-center"
|
>
|
<Button type="link" danger @click="handleRemoveItem(index)">
|
删除
|
</Button>
|
</td>
|
</tr>
|
<tr v-if="!items.length">
|
<td
|
:colspan="formType === 'detail' ? 6 : 7"
|
class="border border-gray-200 px-2 py-4 text-center text-gray-400"
|
>
|
暂无明细,请添加
|
</td>
|
</tr>
|
</tbody>
|
</table>
|
</div>
|
</template>
|
</Form>
|
</Modal>
|
</template>
|