fix: 修复批量工具门店选择器与组件渲染异常
All checks were successful
Build and Deploy TenantUI / build-and-deploy (push) Successful in 52s

This commit is contained in:
2026-02-26 13:09:45 +08:00
parent 5ec724188e
commit 38a296e8bc
7 changed files with 76 additions and 53 deletions

View File

@@ -1,5 +1,6 @@
<script setup lang="ts">
import type { UploadProps } from 'ant-design-vue';
import { Button, Select, Space, Upload } from 'ant-design-vue';
interface Props {
categoryOptions: Array<{ label: string; value: string }>;
@@ -48,7 +49,7 @@ function setExportCategoryIds(value: unknown) {
<div class="pbt-sub-cards">
<article class="pbt-sub-card">
<h4>导入商品</h4>
<a-upload-dragger
<Upload.Dragger
:show-upload-list="false"
accept=".xlsx"
:before-upload="beforeUpload"
@@ -56,25 +57,25 @@ function setExportCategoryIds(value: unknown) {
<p class="pbt-upload-icon">XLSX</p>
<p class="pbt-upload-title">点击或拖拽 Excel 文件到此处上传</p>
<p class="pbt-upload-tip">仅支持 .xlsx建议不超过 10MB</p>
</a-upload-dragger>
</Upload.Dragger>
<div class="pbt-upload-file" v-if="props.selectedFileName">
已选择{{ props.selectedFileName }}
</div>
<a-space class="pbt-upload-actions">
<a-button
<Space class="pbt-upload-actions">
<Button
:loading="props.submitting"
@click="emit('downloadTemplate')"
>
下载导入模板
</a-button>
<a-button
</Button>
<Button
type="primary"
:loading="props.submitting"
@click="emit('submitImport')"
>
开始导入
</a-button>
</a-space>
</Button>
</Space>
</article>
<article class="pbt-sub-card">
@@ -99,7 +100,7 @@ function setExportCategoryIds(value: unknown) {
</button>
</div>
<a-select
<Select
v-if="props.exportScopeType === 'category'"
mode="multiple"
class="pbt-select-wide"
@@ -110,18 +111,19 @@ function setExportCategoryIds(value: unknown) {
/>
</div>
<a-button
<Button
type="primary"
:loading="props.submitting"
@click="emit('submitExport')"
>
导出 Excel
</a-button>
</Button>
</article>
</div>
<footer class="pbt-actions">
<a-button @click="emit('close')">关闭</a-button>
<Button @click="emit('close')">关闭</Button>
</footer>
</section>
</template>

View File

@@ -1,4 +1,6 @@
<script setup lang="ts">
import { Button, Select } from 'ant-design-vue';
interface Props {
categoryOptions: Array<{ label: string; value: string }>;
estimatedCount: number;
@@ -38,7 +40,7 @@ function setTargetCategory(value: unknown) {
<div class="pbt-step-label">
<span class="num">1</span> 源分类可选
</div>
<a-select
<Select
:value="props.sourceCategoryId"
allow-clear
class="pbt-select-narrow"
@@ -50,7 +52,7 @@ function setTargetCategory(value: unknown) {
<div class="pbt-step">
<div class="pbt-step-label"><span class="num">2</span> 目标分类</div>
<a-select
<Select
:value="props.targetCategoryId"
class="pbt-select-narrow"
:options="props.categoryOptions"
@@ -64,14 +66,15 @@ function setTargetCategory(value: unknown) {
</div>
<footer class="pbt-actions">
<a-button
<Button
type="primary"
:loading="props.submitting"
@click="emit('submit')"
>
确认移动
</a-button>
<a-button @click="emit('close')">取消</a-button>
</Button>
<Button @click="emit('close')">取消</Button>
</footer>
</section>
</template>

View File

@@ -2,6 +2,7 @@
import type { BatchPricePreviewRow, BatchScopeType } from '../types';
import { computed } from 'vue';
import { Button, InputNumber, Select, Table } from 'ant-design-vue';
interface Props {
amount: number;
@@ -85,8 +86,9 @@ function setScopeProductIds(value: unknown) {
emit('update:scopeProductIds', normalizeArray(value));
}
function setAmount(value: null | number) {
emit('update:amount', Number(value ?? 0));
function setAmount(value: null | number | string) {
const parsed = Number(value ?? 0);
emit('update:amount', Number.isFinite(parsed) ? parsed : 0);
}
</script>
@@ -111,7 +113,7 @@ function setAmount(value: null | number) {
{{ item.label }}
</button>
</div>
<a-select
<Select
v-if="props.scopeType === 'category'"
mode="multiple"
:value="props.scopeCategoryIds"
@@ -120,7 +122,7 @@ function setAmount(value: null | number) {
class="pbt-select-wide"
@update:value="setScopeCategoryIds"
/>
<a-select
<Select
v-if="props.scopeType === 'manual'"
mode="multiple"
:value="props.scopeProductIds"
@@ -158,16 +160,16 @@ function setAmount(value: null | number) {
{{ item.label }}
</button>
</div>
<a-input-number
<InputNumber
:value="props.amount"
:min="0"
:step="0.1"
class="pbt-number"
@update:value="setAmount"
/>
<a-button :loading="props.previewLoading" @click="emit('preview')">
<Button :loading="props.previewLoading" @click="emit('preview')">
更新预览
</a-button>
</Button>
</div>
</div>
@@ -176,7 +178,7 @@ function setAmount(value: null | number) {
<span class="num">3</span>
预览 {{ props.previewTotal }} 个商品展示前 50
</div>
<a-table
<Table
class="pbt-table"
size="small"
:columns="columns"
@@ -199,18 +201,19 @@ function setAmount(value: null | number) {
</span>
</template>
</template>
</a-table>
</Table>
</div>
<footer class="pbt-actions">
<a-button
<Button
type="primary"
:loading="props.submitting"
@click="emit('submit')"
>
确认调价
</a-button>
<a-button @click="emit('close')">取消</a-button>
</Button>
<Button @click="emit('close')">取消</Button>
</footer>
</section>
</template>

View File

@@ -1,5 +1,6 @@
<script setup lang="ts">
import type { BatchScopeType } from '../types';
import { Button, Select } from 'ant-design-vue';
interface Props {
action: 'off' | 'on';
@@ -74,7 +75,7 @@ function setScopeProductIds(value: unknown) {
</button>
</div>
<a-select
<Select
v-if="props.scopeType === 'category'"
mode="multiple"
:value="props.scopeCategoryIds"
@@ -84,7 +85,7 @@ function setScopeProductIds(value: unknown) {
@update:value="setScopeCategoryIds"
/>
<a-select
<Select
v-if="props.scopeType === 'manual'"
mode="multiple"
:value="props.scopeProductIds"
@@ -116,14 +117,15 @@ function setScopeProductIds(value: unknown) {
</div>
<footer class="pbt-actions">
<a-button
<Button
type="primary"
:loading="props.submitting"
@click="emit('submit')"
>
确认执行
</a-button>
<a-button @click="emit('close')">取消</a-button>
</Button>
<Button @click="emit('close')">取消</Button>
</footer>
</section>
</template>

View File

@@ -1,4 +1,6 @@
<script setup lang="ts">
import { Button, Checkbox, Input, Select, Space } from 'ant-design-vue';
interface Props {
open: boolean;
productIds: string[];
@@ -62,7 +64,7 @@ function setSyncStatus(value: boolean | string | undefined) {
<div class="pbt-step">
<div class="pbt-step-label"><span class="num">1</span> 源门店</div>
<a-input
<Input
:value="props.sourceStoreName"
disabled
class="pbt-select-narrow"
@@ -71,7 +73,7 @@ function setSyncStatus(value: boolean | string | undefined) {
<div class="pbt-step">
<div class="pbt-step-label"><span class="num">2</span> 目标门店</div>
<a-select
<Select
mode="multiple"
:value="props.targetStoreIds"
:options="props.targetStoreOptions"
@@ -83,7 +85,7 @@ function setSyncStatus(value: boolean | string | undefined) {
<div class="pbt-step">
<div class="pbt-step-label"><span class="num">3</span> 同步商品</div>
<a-select
<Select
mode="multiple"
:value="props.productIds"
:options="props.productOptions"
@@ -95,28 +97,29 @@ function setSyncStatus(value: boolean | string | undefined) {
<div class="pbt-step">
<div class="pbt-step-label"><span class="num">4</span> 同步选项</div>
<a-space>
<a-checkbox :checked="props.syncPrice" @update:checked="setSyncPrice">
<Space>
<Checkbox :checked="props.syncPrice" @update:checked="setSyncPrice">
价格
</a-checkbox>
<a-checkbox :checked="props.syncStock" @update:checked="setSyncStock">
</Checkbox>
<Checkbox :checked="props.syncStock" @update:checked="setSyncStock">
库存
</a-checkbox>
<a-checkbox :checked="props.syncStatus" @update:checked="setSyncStatus">
</Checkbox>
<Checkbox :checked="props.syncStatus" @update:checked="setSyncStatus">
状态
</a-checkbox>
</a-space>
</Checkbox>
</Space>
</div>
<footer class="pbt-actions">
<a-button
<Button
type="primary"
:loading="props.submitting"
@click="emit('submit')"
>
确认同步
</a-button>
<a-button @click="emit('close')">取消</a-button>
</Button>
<Button @click="emit('close')">取消</Button>
</footer>
</section>
</template>

View File

@@ -2,6 +2,7 @@
import type { BatchToolCard, BatchToolKey } from '../types';
import { IconifyIcon } from '@vben/icons';
import { Button } from 'ant-design-vue';
interface Props {
activeTool: BatchToolKey | null;
@@ -29,9 +30,10 @@ const emit = defineEmits<Emits>();
</div>
<h3 class="pbt-card-name">{{ card.title }}</h3>
<p class="pbt-card-desc">{{ card.description }}</p>
<a-button type="primary" size="small" @click="emit('toggle', card.key)">
<Button type="primary" size="small" @click="emit('toggle', card.key)">
{{ props.activeTool === card.key ? '收起' : '开始操作' }}
</a-button>
</Button>
</article>
</div>
</template>

View File

@@ -1,4 +1,6 @@
<script setup lang="ts">
import { Select } from 'ant-design-vue';
interface Props {
isStoreLoading: boolean;
selectedStoreId: string;
@@ -12,8 +14,13 @@ interface Emits {
const props = defineProps<Props>();
const emit = defineEmits<Emits>();
function setStore(value: string | undefined) {
emit('update:selectedStoreId', value ?? '');
function setStore(value: unknown) {
if (typeof value === 'string' || typeof value === 'number') {
emit('update:selectedStoreId', String(value));
return;
}
emit('update:selectedStoreId', '');
}
</script>
@@ -21,7 +28,7 @@ function setStore(value: string | undefined) {
<div class="pbt-toolbar">
<div class="pbt-toolbar-main">
<span class="pbt-toolbar-label">门店</span>
<a-select
<Select
class="pbt-toolbar-store"
:value="props.selectedStoreId"
:options="props.storeOptions"
@@ -33,3 +40,4 @@ function setStore(value: string | undefined) {
<div class="pbt-toolbar-tip">选择门店后工具仅作用于当前门店商品</div>
</div>
</template>