style(project): format product detail split modules

This commit is contained in:
2026-02-22 10:14:04 +08:00
parent d6e5138e53
commit 37b3ef693d
5 changed files with 60 additions and 34 deletions

View File

@@ -69,7 +69,7 @@ function ensureProductDetailRoute(
path: PRODUCT_DETAIL_PATH,
component: '/views/product/detail/index.vue',
meta: {
...(listMeta ?? {}),
...listMeta,
title: '商品详情',
hideInMenu: true,
},

View File

@@ -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) => {

View File

@@ -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)),

View File

@@ -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;
}

View File

@@ -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';