add product
This commit is contained in:
@@ -274,6 +274,9 @@ const customerDisplayText = computed(() => {
|
||||
|
||||
async function handleCustomerChange(value: string | string[]): Promise<void> {
|
||||
selectedCustomerIdList.value = Array.isArray(value) ? value : [value];
|
||||
if (isPackagePurchaseSelected.value) {
|
||||
resetPackageRequestNo();
|
||||
}
|
||||
await loadSelectedCustomerList();
|
||||
await loadRecentRecordList();
|
||||
}
|
||||
@@ -601,6 +604,7 @@ const {
|
||||
handleEventSelectionChange,
|
||||
applySelectedPackageEvent,
|
||||
resetPackagePurchaseForm,
|
||||
resetPackageRequestNo,
|
||||
submitPackagePurchase,
|
||||
validatePackagePurchaseForm
|
||||
} = usePackagePurchaseRecord({
|
||||
@@ -635,8 +639,9 @@ async function submitRecord(): Promise<void> {
|
||||
return;
|
||||
}
|
||||
|
||||
const packageResult = isPackagePurchaseSelected.value ? await submitPackagePurchase() : undefined;
|
||||
const success = isPackagePurchaseSelected.value
|
||||
? await submitPackagePurchase()
|
||||
? !!packageResult?.id
|
||||
: await submitEventRecords();
|
||||
if (!success) {
|
||||
return;
|
||||
@@ -645,6 +650,10 @@ async function submitRecord(): Promise<void> {
|
||||
await loadRecentRecordList();
|
||||
await settingStore.playRegisterSuccessSound();
|
||||
Message.success(isPackagePurchaseSelected.value ? "套餐购买已提交" : "登记已提交");
|
||||
if (packageResult?.id) {
|
||||
await router.replace(`/management/customer-packages/${packageResult.id}`);
|
||||
return;
|
||||
}
|
||||
await router.replace("/customers");
|
||||
} finally {
|
||||
isSaving.value = false;
|
||||
|
||||
@@ -718,7 +718,7 @@ onUnmounted(() => {
|
||||
flex-direction: column;
|
||||
|
||||
.search-input {
|
||||
--td-input-vertical-padding: 8px;
|
||||
--td-input-vertical-padding: 8px 14px;
|
||||
|
||||
border: 1px solid rgba(148, 163, 184, .28);
|
||||
z-index: 1;
|
||||
|
||||
@@ -29,9 +29,9 @@
|
||||
</div>
|
||||
<t-form-item
|
||||
v-for="(item, index) in itemList"
|
||||
:key="`${index}-${item.productName}-${item.unit}`"
|
||||
:key="`${index}-${item.productId}-${item.productUnitId}`"
|
||||
class="item"
|
||||
:label="item.productName"
|
||||
:label="getItemLabel(item)"
|
||||
>
|
||||
<t-input
|
||||
:model-value="item.totalQuantity"
|
||||
@@ -43,7 +43,7 @@
|
||||
@update:model-value="updateItemQuantity(index, $event)"
|
||||
>
|
||||
<template #suffix-icon>
|
||||
<span class="unit" v-text="item.unit" />
|
||||
<span class="unit" v-text="getItemUnit(item)" />
|
||||
</template>
|
||||
</t-input>
|
||||
</t-form-item>
|
||||
@@ -68,6 +68,15 @@ const props = defineProps<Props>();
|
||||
const saleAmount = defineModel<string>("saleAmount", { required: true });
|
||||
const itemList = defineModel<PackagePurchaseItem[]>("itemList", { required: true });
|
||||
|
||||
function getItemLabel(item: PackagePurchaseItem): string {
|
||||
const configItem = props.packageConfig?.itemList?.find(config => config.productId === item.productId && config.productUnitId === item.productUnitId);
|
||||
return configItem ? `${configItem.productNameSnapshot || "未命名产品"} · ${configItem.unitSnapshot || "未设置单位"}` : "产品权益";
|
||||
}
|
||||
|
||||
function getItemUnit(item: PackagePurchaseItem): string {
|
||||
return props.packageConfig?.itemList?.find(config => config.productId === item.productId && config.productUnitId === item.productUnitId)?.unitSnapshot || "";
|
||||
}
|
||||
|
||||
function updateItemQuantity(index: number, value: string | number): void {
|
||||
itemList.value = itemList.value.map((item, itemIndex) => itemIndex === index ? {
|
||||
...item,
|
||||
|
||||
@@ -2,7 +2,7 @@ import { computed, ref, type Ref } from "vue";
|
||||
import PackageAPI from "@/api/PackageAPI";
|
||||
import type { Customer } from "@/types/Customer";
|
||||
import type { EventItem } from "@/types/EventItem";
|
||||
import type { PackagePurchaseItem } from "@/types/Package";
|
||||
import type { GaoCustomerPackage, PackagePurchaseItem } from "@/types/Package";
|
||||
import { isPackagePurchaseEvent } from "@/utils/event";
|
||||
import { createPackageRequestNo, formatPackageAmountInput, normalizePackageQuantity, parsePackageAmount } from "@/utils/package";
|
||||
import { permissionCodes } from "@/utils/permission";
|
||||
@@ -37,6 +37,7 @@ export function usePackagePurchaseRecord(options: UsePackagePurchaseRecordOption
|
||||
const canPriceOverride = computed(() => options.hasPermission(permissionCodes.customerPackage.priceOverride));
|
||||
const saleAmountText = ref("");
|
||||
const packagePurchaseItemList = ref<PackagePurchaseItem[]>([]);
|
||||
const packageRequestNo = ref("");
|
||||
|
||||
function handleEventSelectionChange(eventIdList: string[]): void {
|
||||
const packageEvent = eventIdList
|
||||
@@ -65,8 +66,8 @@ export function usePackagePurchaseRecord(options: UsePackagePurchaseRecordOption
|
||||
|
||||
saleAmountText.value = formatPackageAmountInput(config.standardAmount);
|
||||
packagePurchaseItemList.value = (config.itemList || []).map((item, index) => ({
|
||||
productName: item.productName,
|
||||
unit: item.unit,
|
||||
productId: item.productId,
|
||||
productUnitId: item.productUnitId,
|
||||
totalQuantity: normalizePackageQuantity(item.defaultQuantity) || "",
|
||||
sort: item.sort ?? index,
|
||||
remark: item.remark ?? null
|
||||
@@ -76,25 +77,33 @@ export function usePackagePurchaseRecord(options: UsePackagePurchaseRecordOption
|
||||
function resetPackagePurchaseForm(): void {
|
||||
saleAmountText.value = "";
|
||||
packagePurchaseItemList.value = [];
|
||||
packageRequestNo.value = "";
|
||||
}
|
||||
|
||||
async function submitPackagePurchase(): Promise<boolean> {
|
||||
function resetPackageRequestNo(): void {
|
||||
packageRequestNo.value = "";
|
||||
}
|
||||
|
||||
async function submitPackagePurchase(): Promise<GaoCustomerPackage | undefined> {
|
||||
const eventId = selectedPackageEvent.value?.id;
|
||||
const customerId = options.selectedCustomerList.value[0]?.id;
|
||||
const saleAmount = parsePackageAmount(saleAmountText.value);
|
||||
if (!eventId || !customerId || saleAmount === undefined) {
|
||||
return false;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
await PackageAPI.purchase({
|
||||
requestNo: createPackageRequestNo(),
|
||||
if (!packageRequestNo.value) {
|
||||
packageRequestNo.value = createPackageRequestNo();
|
||||
}
|
||||
const result = await PackageAPI.purchase({
|
||||
requestNo: packageRequestNo.value,
|
||||
eventId,
|
||||
customerId,
|
||||
saleAmount,
|
||||
purchasedAt: options.buildRegisteredAt(),
|
||||
itemList: packagePurchaseItemList.value.map((item, index) => ({
|
||||
productName: item.productName.trim(),
|
||||
unit: item.unit.trim(),
|
||||
productId: item.productId,
|
||||
productUnitId: item.productUnitId,
|
||||
totalQuantity: normalizePackageQuantity(item.totalQuantity)!,
|
||||
sort: item.sort ?? index,
|
||||
remark: item.remark ?? null
|
||||
@@ -105,7 +114,7 @@ export function usePackagePurchaseRecord(options: UsePackagePurchaseRecordOption
|
||||
})),
|
||||
remark: options.note.value.trim() || null
|
||||
});
|
||||
return true;
|
||||
return result;
|
||||
}
|
||||
|
||||
function validatePackagePurchaseForm(): boolean {
|
||||
@@ -135,8 +144,8 @@ export function usePackagePurchaseRecord(options: UsePackagePurchaseRecordOption
|
||||
}
|
||||
for (const item of packagePurchaseItemList.value) {
|
||||
const quantity = normalizePackageQuantity(item.totalQuantity);
|
||||
if (!item.productName.trim() || !item.unit.trim() || !quantity || quantity === "0") {
|
||||
Message.warning("产品名称、单位和正数量不能为空");
|
||||
if (!item.productId || !item.productUnitId || !quantity || quantity === "0") {
|
||||
Message.warning("产品单位和正数量不能为空");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -159,6 +168,7 @@ export function usePackagePurchaseRecord(options: UsePackagePurchaseRecordOption
|
||||
handleEventSelectionChange,
|
||||
applySelectedPackageEvent,
|
||||
resetPackagePurchaseForm,
|
||||
resetPackageRequestNo,
|
||||
submitPackagePurchase,
|
||||
validatePackagePurchaseForm
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user