style(project): format product detail split modules
This commit is contained in:
@@ -69,7 +69,7 @@ function ensureProductDetailRoute(
|
||||
path: PRODUCT_DETAIL_PATH,
|
||||
component: '/views/product/detail/index.vue',
|
||||
meta: {
|
||||
...(listMeta ?? {}),
|
||||
...listMeta,
|
||||
title: '商品详情',
|
||||
hideInMenu: true,
|
||||
},
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import type { Ref } from 'vue';
|
||||
|
||||
import type { ProductDetailFormState } from '../../types';
|
||||
|
||||
import type { ProductPickerItemDto } from '#/api/product';
|
||||
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { searchProductPickerApi } from '#/api/product';
|
||||
|
||||
import type { ProductDetailFormState } from '../../types';
|
||||
|
||||
interface CreateProductDetailComboActionsOptions {
|
||||
comboPickerCurrentGroupIndex: Ref<number>;
|
||||
comboPickerKeyword: Ref<string>;
|
||||
@@ -51,7 +51,9 @@ export function createProductDetailComboActions(
|
||||
|
||||
function removeComboGroup(groupIndex: number) {
|
||||
if (groupIndex < 0 || groupIndex >= form.comboGroups.length) return;
|
||||
form.comboGroups = form.comboGroups.filter((_, index) => index !== groupIndex);
|
||||
form.comboGroups = form.comboGroups.filter(
|
||||
(_, index) => index !== groupIndex,
|
||||
);
|
||||
form.comboGroups.forEach((group, index) => {
|
||||
group.sortOrder = index + 1;
|
||||
});
|
||||
@@ -90,7 +92,11 @@ export function createProductDetailComboActions(
|
||||
}
|
||||
}
|
||||
|
||||
function setComboItemQuantity(groupIndex: number, itemIndex: number, value: number) {
|
||||
function setComboItemQuantity(
|
||||
groupIndex: number,
|
||||
itemIndex: number,
|
||||
value: number,
|
||||
) {
|
||||
const group = form.comboGroups[groupIndex];
|
||||
if (!group) return;
|
||||
const item = group.items[itemIndex];
|
||||
@@ -117,7 +123,9 @@ export function createProductDetailComboActions(
|
||||
keyword: comboPickerKeyword.value.trim() || undefined,
|
||||
limit: 100,
|
||||
});
|
||||
comboPickerProducts.value = products.filter((item) => item.id !== form.id);
|
||||
comboPickerProducts.value = products.filter(
|
||||
(item) => item.id !== form.id,
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
comboPickerProducts.value = [];
|
||||
@@ -153,7 +161,9 @@ export function createProductDetailComboActions(
|
||||
return;
|
||||
}
|
||||
|
||||
const currentItemMap = new Map(group.items.map((item) => [item.productId, item]));
|
||||
const currentItemMap = new Map(
|
||||
group.items.map((item) => [item.productId, item]),
|
||||
);
|
||||
|
||||
const selectedProducts = comboPickerSelectedProducts.value;
|
||||
group.items = selectedProducts.map((product, index) => {
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
import type { Ref } from 'vue';
|
||||
import type { Router } from 'vue-router';
|
||||
|
||||
import type {
|
||||
ProductDetailCategoryOption,
|
||||
ProductDetailFormState,
|
||||
} from '../../types';
|
||||
|
||||
import type {
|
||||
ProductAddonGroupDto,
|
||||
ProductDetailDto,
|
||||
@@ -22,11 +27,6 @@ import {
|
||||
saveProductApi,
|
||||
} from '#/api/product';
|
||||
|
||||
import type {
|
||||
ProductDetailCategoryOption,
|
||||
ProductDetailFormState,
|
||||
} from '../../types';
|
||||
|
||||
import { DEFAULT_PRODUCT_DETAIL_FORM } from './constants';
|
||||
import {
|
||||
buildLocalSkuCode,
|
||||
@@ -91,10 +91,10 @@ export function createProductDetailDataActions(
|
||||
form.description = data.description;
|
||||
form.sortWeight = Math.max(0, Number(data.sortWeight || 0));
|
||||
|
||||
form.imageUrls = dedupeTextList([...(data.imageUrls || []), data.imageUrl]).slice(
|
||||
0,
|
||||
5,
|
||||
);
|
||||
form.imageUrls = dedupeTextList([
|
||||
...(data.imageUrls || []),
|
||||
data.imageUrl,
|
||||
]).slice(0, 5);
|
||||
|
||||
form.price = Number(data.price || 0);
|
||||
form.originalPrice =
|
||||
@@ -178,7 +178,9 @@ export function createProductDetailDataActions(
|
||||
|
||||
function removeImage(index: number) {
|
||||
if (index < 0 || index >= form.imageUrls.length) return;
|
||||
form.imageUrls = form.imageUrls.filter((_, itemIndex) => itemIndex !== index);
|
||||
form.imageUrls = form.imageUrls.filter(
|
||||
(_, itemIndex) => itemIndex !== index,
|
||||
);
|
||||
}
|
||||
|
||||
function setPrimaryImage(index: number) {
|
||||
@@ -197,16 +199,18 @@ export function createProductDetailDataActions(
|
||||
|
||||
isLoading.value = true;
|
||||
try {
|
||||
const [detailData, categories, specs, addons, labels] = await Promise.all([
|
||||
getProductDetailApi({
|
||||
storeId: storeId.value,
|
||||
productId: productId.value,
|
||||
}),
|
||||
getProductCategoryListApi(storeId.value),
|
||||
getProductSpecListApi({ storeId: storeId.value }),
|
||||
getProductAddonGroupListApi({ storeId: storeId.value }),
|
||||
getProductLabelListApi({ storeId: storeId.value }),
|
||||
]);
|
||||
const [detailData, categories, specs, addons, labels] = await Promise.all(
|
||||
[
|
||||
getProductDetailApi({
|
||||
storeId: storeId.value,
|
||||
productId: productId.value,
|
||||
}),
|
||||
getProductCategoryListApi(storeId.value),
|
||||
getProductSpecListApi({ storeId: storeId.value }),
|
||||
getProductAddonGroupListApi({ storeId: storeId.value }),
|
||||
getProductLabelListApi({ storeId: storeId.value }),
|
||||
],
|
||||
);
|
||||
|
||||
detail.value = detailData;
|
||||
categoryOptions.value = categories.map((item) => ({
|
||||
@@ -319,7 +323,10 @@ export function createProductDetailDataActions(
|
||||
: null,
|
||||
stock: Math.max(0, Math.floor(Number(item.stock || 0))),
|
||||
isEnabled: item.isEnabled,
|
||||
sortOrder: Math.max(1, Math.floor(Number(item.sortOrder || index + 1))),
|
||||
sortOrder: Math.max(
|
||||
1,
|
||||
Math.floor(Number(item.sortOrder || index + 1)),
|
||||
),
|
||||
attributes: item.attributes.map((attr) => ({
|
||||
templateId: attr.templateId,
|
||||
optionId: attr.optionId,
|
||||
@@ -329,8 +336,14 @@ export function createProductDetailDataActions(
|
||||
form.kind === 'combo'
|
||||
? form.comboGroups.map((group, groupIndex) => ({
|
||||
name: group.name.trim(),
|
||||
minSelect: Math.max(1, Math.floor(Number(group.minSelect || 1))),
|
||||
maxSelect: Math.max(1, Math.floor(Number(group.maxSelect || 1))),
|
||||
minSelect: Math.max(
|
||||
1,
|
||||
Math.floor(Number(group.minSelect || 1)),
|
||||
),
|
||||
maxSelect: Math.max(
|
||||
1,
|
||||
Math.floor(Number(group.maxSelect || 1)),
|
||||
),
|
||||
sortOrder: Math.max(
|
||||
1,
|
||||
Math.floor(Number(group.sortOrder || groupIndex + 1)),
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import type { Ref } from 'vue';
|
||||
|
||||
import type { ProductSpecDto } from '#/api/product';
|
||||
|
||||
import type {
|
||||
ProductDetailFormState,
|
||||
ProductDetailSkuBatchState,
|
||||
ProductDetailSkuRowState,
|
||||
} from '../../types';
|
||||
|
||||
import type { ProductSpecDto } from '#/api/product';
|
||||
|
||||
import {
|
||||
buildLocalSkuCode,
|
||||
buildSkuCombinations,
|
||||
@@ -42,7 +42,10 @@ export function createProductDetailSkuActions(
|
||||
);
|
||||
}
|
||||
|
||||
function getSkuAttrOptionId(row: ProductDetailSkuRowState, templateId: string) {
|
||||
function getSkuAttrOptionId(
|
||||
row: ProductDetailSkuRowState,
|
||||
templateId: string,
|
||||
) {
|
||||
return row.attributes.find((item) => item.templateId === templateId)
|
||||
?.optionId;
|
||||
}
|
||||
|
||||
@@ -15,8 +15,8 @@ import type {
|
||||
import { computed, reactive, ref, watch } from 'vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
import { DEFAULT_PRODUCT_DETAIL_FORM } from './product-detail-page/constants';
|
||||
import { createProductDetailComboActions } from './product-detail-page/combo-actions';
|
||||
import { DEFAULT_PRODUCT_DETAIL_FORM } from './product-detail-page/constants';
|
||||
import { createProductDetailDataActions } from './product-detail-page/data-actions';
|
||||
import { createProductDetailSkuActions } from './product-detail-page/sku-actions';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user