refactor: fix layout for merged decks in PrintPreview

Update PrintPreview to correctly handle dimensions and layer
configurations when multiple decks are merged. Instead of using the
base store for all cards, it now maps each card to its specific
source store to ensure correct grid positioning and styling.
This commit is contained in:
hypercross 2026-05-05 16:46:10 +08:00
parent 4953d33f0f
commit d4de95b465
1 changed files with 33 additions and 12 deletions

View File

@ -26,7 +26,9 @@ export interface PrintPreviewProps {
export function PrintPreview(props: PrintPreviewProps) { export function PrintPreview(props: PrintPreviewProps) {
const { store } = props; const { store } = props;
// 合并的卡牌列表:主牌组 + 选中的其他牌组 // ---- 跨牌组合并 ----
// 用户选中的额外牌组 ID 列表
const [selectedDeckIds, setSelectedDeckIds] = createSignal<string[]>([]); const [selectedDeckIds, setSelectedDeckIds] = createSignal<string[]>([]);
// 当某个已选中的牌组被卸载时,自动从选中列表中移除 // 当某个已选中的牌组被卸载时,自动从选中列表中移除
@ -38,18 +40,33 @@ export function PrintPreview(props: PrintPreviewProps) {
} }
}); });
const mergedCards = createMemo(() => { // 仅额外牌组的卡牌(不含主牌组),传给 usePageLayout 避免重复
const base = store.state.cards as CardData[]; const extraCards = createMemo(() => {
const extras = selectedDeckIds() return selectedDeckIds()
.map((id) => getDeckById(id)) .map((id) => getDeckById(id))
.filter(Boolean) .filter(Boolean)
.flatMap((entry) => entry!.store.state.cards as CardData[]); .flatMap((entry) => entry!.store.state.cards as CardData[]);
return [...base, ...extras];
}); });
const mergedCardCount = () => mergedCards().length; // 卡牌 → 来源 store 的映射,用于渲染时选择正确的图层配置
const cardStoreMap = createMemo(() => {
const map = new Map<CardData, DeckStore>();
for (const id of selectedDeckIds()) {
const entry = getDeckById(id);
if (entry) {
for (const card of entry.store.state.cards as CardData[]) {
map.set(card, entry.store);
}
}
}
return map;
});
const { getA4Size, pages, cropMarks } = usePageLayout(store, mergedCards); const mergedCardCount = () => store.state.cards.length + extraCards().length;
// ---- 布局 & 导出 hooks ----
const { getA4Size, pages, cropMarks } = usePageLayout(store, extraCards);
const { exportToPDF } = usePDFExport(store, props.onClose); const { exportToPDF } = usePDFExport(store, props.onClose);
const { generatePltData } = usePlotterExport(store); const { generatePltData } = usePlotterExport(store);
@ -211,6 +228,10 @@ export function PrintPreview(props: PrintPreviewProps) {
store.state.cornerRadius, store.state.cornerRadius,
); );
// 查找该卡牌所属的 store主牌组用 store合并牌组用各自的 store
const cardStore =
cardStoreMap().get(card.data) || store;
return ( return (
<g class="card-group"> <g class="card-group">
<Show when={shapeClipPath}> <Show when={shapeClipPath}>
@ -238,14 +259,14 @@ export function PrintPreview(props: PrintPreviewProps) {
class="absolute" class="absolute"
style={{ style={{
position: "absolute", position: "absolute",
left: `${store.state.dimensions?.gridOriginX}mm`, left: `${cardStore.state.dimensions?.gridOriginX}mm`,
top: `${store.state.dimensions?.gridOriginY}mm`, top: `${cardStore.state.dimensions?.gridOriginY}mm`,
width: `${store.state.dimensions?.gridAreaWidth}mm`, width: `${cardStore.state.dimensions?.gridAreaWidth}mm`,
height: `${store.state.dimensions?.gridAreaHeight}mm`, height: `${cardStore.state.dimensions?.gridAreaHeight}mm`,
}} }}
> >
<CardLayer <CardLayer
store={store} store={cardStore}
cardData={card.data} cardData={card.data}
side={card.side || "front"} side={card.side || "front"}
/> />