<script lang="ts" setup>
|
import type { MesProMaintenancePlanApi } from '#/api/mes/pro/maintenance-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 {
|
createPlan,
|
getPlan,
|
updatePlan,
|
} from '#/api/mes/pro/maintenance-plan';
|
import { MdItemSelect } from '#/views/mes/md/item/components';
|
import { $t } from '#/locales';
|
|
import type { FormType } from '../data';
|
import { useFormSchema } from '../data';
|
|
const emit = defineEmits(['success']);
|
const formData = ref<MesProMaintenancePlanApi.MaintenancePlan>();
|
const formType = ref<FormType>('create');
|
const items = ref<MesProMaintenancePlanApi.PlanItem[]>([]);
|
|
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({
|
itemId: undefined as unknown as number,
|
itemName: '',
|
itemCode: '',
|
unitMeasureName: '',
|
quantity: 1,
|
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.itemId = item?.id;
|
row.itemName = item?.name;
|
row.itemCode = item?.code;
|
row.unitMeasureName = 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.itemId || !item.quantity)) {
|
message.error('请完善备件需求的产品与数量');
|
return;
|
}
|
modalApi.lock();
|
const data =
|
(await formApi.getValues()) as MesProMaintenancePlanApi.MaintenancePlan;
|
data.items = items.value.map((item) => ({
|
itemId: item.itemId,
|
quantity: item.quantity,
|
remark: item.remark,
|
}));
|
try {
|
await (formType.value === 'create'
|
? createPlan(data)
|
: updatePlan(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 getPlan(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">备注</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">
|
<MdItemSelect
|
v-if="formType !== 'detail'"
|
:model-value="item.itemId"
|
placeholder="请选择物料/备件"
|
@change="handleItemSelect(index, $event)"
|
/>
|
<span v-else>{{ item.itemName }}</span>
|
</td>
|
<td class="border border-gray-200 px-2 py-1 text-center">
|
{{ item.unitMeasureName || '-' }}
|
</td>
|
<td class="border border-gray-200 px-2 py-1">
|
<InputNumber
|
v-if="formType !== 'detail'"
|
v-model:value="item.quantity"
|
class="!w-full"
|
:min="0.01"
|
:precision="2"
|
/>
|
<span v-else>{{ item.quantity }}</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' ? 5 : 6"
|
class="border border-gray-200 px-2 py-4 text-center text-gray-400"
|
>
|
暂无备件需求,请添加
|
</td>
|
</tr>
|
</tbody>
|
</table>
|
</div>
|
</template>
|
</Form>
|
</Modal>
|
</template>
|