fix: 修复批量工具门店选择器与组件渲染异常
All checks were successful
Build and Deploy TenantUI / build-and-deploy (push) Successful in 52s
All checks were successful
Build and Deploy TenantUI / build-and-deploy (push) Successful in 52s
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { UploadProps } from 'ant-design-vue';
|
import type { UploadProps } from 'ant-design-vue';
|
||||||
|
import { Button, Select, Space, Upload } from 'ant-design-vue';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
categoryOptions: Array<{ label: string; value: string }>;
|
categoryOptions: Array<{ label: string; value: string }>;
|
||||||
@@ -48,7 +49,7 @@ function setExportCategoryIds(value: unknown) {
|
|||||||
<div class="pbt-sub-cards">
|
<div class="pbt-sub-cards">
|
||||||
<article class="pbt-sub-card">
|
<article class="pbt-sub-card">
|
||||||
<h4>导入商品</h4>
|
<h4>导入商品</h4>
|
||||||
<a-upload-dragger
|
<Upload.Dragger
|
||||||
:show-upload-list="false"
|
:show-upload-list="false"
|
||||||
accept=".xlsx"
|
accept=".xlsx"
|
||||||
:before-upload="beforeUpload"
|
:before-upload="beforeUpload"
|
||||||
@@ -56,25 +57,25 @@ function setExportCategoryIds(value: unknown) {
|
|||||||
<p class="pbt-upload-icon">XLSX</p>
|
<p class="pbt-upload-icon">XLSX</p>
|
||||||
<p class="pbt-upload-title">点击或拖拽 Excel 文件到此处上传</p>
|
<p class="pbt-upload-title">点击或拖拽 Excel 文件到此处上传</p>
|
||||||
<p class="pbt-upload-tip">仅支持 .xlsx,建议不超过 10MB</p>
|
<p class="pbt-upload-tip">仅支持 .xlsx,建议不超过 10MB</p>
|
||||||
</a-upload-dragger>
|
</Upload.Dragger>
|
||||||
<div class="pbt-upload-file" v-if="props.selectedFileName">
|
<div class="pbt-upload-file" v-if="props.selectedFileName">
|
||||||
已选择:{{ props.selectedFileName }}
|
已选择:{{ props.selectedFileName }}
|
||||||
</div>
|
</div>
|
||||||
<a-space class="pbt-upload-actions">
|
<Space class="pbt-upload-actions">
|
||||||
<a-button
|
<Button
|
||||||
:loading="props.submitting"
|
:loading="props.submitting"
|
||||||
@click="emit('downloadTemplate')"
|
@click="emit('downloadTemplate')"
|
||||||
>
|
>
|
||||||
下载导入模板
|
下载导入模板
|
||||||
</a-button>
|
</Button>
|
||||||
<a-button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
:loading="props.submitting"
|
:loading="props.submitting"
|
||||||
@click="emit('submitImport')"
|
@click="emit('submitImport')"
|
||||||
>
|
>
|
||||||
开始导入
|
开始导入
|
||||||
</a-button>
|
</Button>
|
||||||
</a-space>
|
</Space>
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
<article class="pbt-sub-card">
|
<article class="pbt-sub-card">
|
||||||
@@ -99,7 +100,7 @@ function setExportCategoryIds(value: unknown) {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a-select
|
<Select
|
||||||
v-if="props.exportScopeType === 'category'"
|
v-if="props.exportScopeType === 'category'"
|
||||||
mode="multiple"
|
mode="multiple"
|
||||||
class="pbt-select-wide"
|
class="pbt-select-wide"
|
||||||
@@ -110,18 +111,19 @@ function setExportCategoryIds(value: unknown) {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a-button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
:loading="props.submitting"
|
:loading="props.submitting"
|
||||||
@click="emit('submitExport')"
|
@click="emit('submitExport')"
|
||||||
>
|
>
|
||||||
导出 Excel
|
导出 Excel
|
||||||
</a-button>
|
</Button>
|
||||||
</article>
|
</article>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer class="pbt-actions">
|
<footer class="pbt-actions">
|
||||||
<a-button @click="emit('close')">关闭</a-button>
|
<Button @click="emit('close')">关闭</Button>
|
||||||
</footer>
|
</footer>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { Button, Select } from 'ant-design-vue';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
categoryOptions: Array<{ label: string; value: string }>;
|
categoryOptions: Array<{ label: string; value: string }>;
|
||||||
estimatedCount: number;
|
estimatedCount: number;
|
||||||
@@ -38,7 +40,7 @@ function setTargetCategory(value: unknown) {
|
|||||||
<div class="pbt-step-label">
|
<div class="pbt-step-label">
|
||||||
<span class="num">1</span> 源分类(可选)
|
<span class="num">1</span> 源分类(可选)
|
||||||
</div>
|
</div>
|
||||||
<a-select
|
<Select
|
||||||
:value="props.sourceCategoryId"
|
:value="props.sourceCategoryId"
|
||||||
allow-clear
|
allow-clear
|
||||||
class="pbt-select-narrow"
|
class="pbt-select-narrow"
|
||||||
@@ -50,7 +52,7 @@ function setTargetCategory(value: unknown) {
|
|||||||
|
|
||||||
<div class="pbt-step">
|
<div class="pbt-step">
|
||||||
<div class="pbt-step-label"><span class="num">2</span> 目标分类</div>
|
<div class="pbt-step-label"><span class="num">2</span> 目标分类</div>
|
||||||
<a-select
|
<Select
|
||||||
:value="props.targetCategoryId"
|
:value="props.targetCategoryId"
|
||||||
class="pbt-select-narrow"
|
class="pbt-select-narrow"
|
||||||
:options="props.categoryOptions"
|
:options="props.categoryOptions"
|
||||||
@@ -64,14 +66,15 @@ function setTargetCategory(value: unknown) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer class="pbt-actions">
|
<footer class="pbt-actions">
|
||||||
<a-button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
:loading="props.submitting"
|
:loading="props.submitting"
|
||||||
@click="emit('submit')"
|
@click="emit('submit')"
|
||||||
>
|
>
|
||||||
确认移动
|
确认移动
|
||||||
</a-button>
|
</Button>
|
||||||
<a-button @click="emit('close')">取消</a-button>
|
<Button @click="emit('close')">取消</Button>
|
||||||
</footer>
|
</footer>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import type { BatchPricePreviewRow, BatchScopeType } from '../types';
|
import type { BatchPricePreviewRow, BatchScopeType } from '../types';
|
||||||
|
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
|
import { Button, InputNumber, Select, Table } from 'ant-design-vue';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
amount: number;
|
amount: number;
|
||||||
@@ -85,8 +86,9 @@ function setScopeProductIds(value: unknown) {
|
|||||||
emit('update:scopeProductIds', normalizeArray(value));
|
emit('update:scopeProductIds', normalizeArray(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
function setAmount(value: null | number) {
|
function setAmount(value: null | number | string) {
|
||||||
emit('update:amount', Number(value ?? 0));
|
const parsed = Number(value ?? 0);
|
||||||
|
emit('update:amount', Number.isFinite(parsed) ? parsed : 0);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -111,7 +113,7 @@ function setAmount(value: null | number) {
|
|||||||
{{ item.label }}
|
{{ item.label }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<a-select
|
<Select
|
||||||
v-if="props.scopeType === 'category'"
|
v-if="props.scopeType === 'category'"
|
||||||
mode="multiple"
|
mode="multiple"
|
||||||
:value="props.scopeCategoryIds"
|
:value="props.scopeCategoryIds"
|
||||||
@@ -120,7 +122,7 @@ function setAmount(value: null | number) {
|
|||||||
class="pbt-select-wide"
|
class="pbt-select-wide"
|
||||||
@update:value="setScopeCategoryIds"
|
@update:value="setScopeCategoryIds"
|
||||||
/>
|
/>
|
||||||
<a-select
|
<Select
|
||||||
v-if="props.scopeType === 'manual'"
|
v-if="props.scopeType === 'manual'"
|
||||||
mode="multiple"
|
mode="multiple"
|
||||||
:value="props.scopeProductIds"
|
:value="props.scopeProductIds"
|
||||||
@@ -158,16 +160,16 @@ function setAmount(value: null | number) {
|
|||||||
{{ item.label }}
|
{{ item.label }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<a-input-number
|
<InputNumber
|
||||||
:value="props.amount"
|
:value="props.amount"
|
||||||
:min="0"
|
:min="0"
|
||||||
:step="0.1"
|
:step="0.1"
|
||||||
class="pbt-number"
|
class="pbt-number"
|
||||||
@update:value="setAmount"
|
@update:value="setAmount"
|
||||||
/>
|
/>
|
||||||
<a-button :loading="props.previewLoading" @click="emit('preview')">
|
<Button :loading="props.previewLoading" @click="emit('preview')">
|
||||||
更新预览
|
更新预览
|
||||||
</a-button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -176,7 +178,7 @@ function setAmount(value: null | number) {
|
|||||||
<span class="num">3</span>
|
<span class="num">3</span>
|
||||||
预览(共 {{ props.previewTotal }} 个商品,展示前 50 条)
|
预览(共 {{ props.previewTotal }} 个商品,展示前 50 条)
|
||||||
</div>
|
</div>
|
||||||
<a-table
|
<Table
|
||||||
class="pbt-table"
|
class="pbt-table"
|
||||||
size="small"
|
size="small"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
@@ -199,18 +201,19 @@ function setAmount(value: null | number) {
|
|||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</a-table>
|
</Table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer class="pbt-actions">
|
<footer class="pbt-actions">
|
||||||
<a-button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
:loading="props.submitting"
|
:loading="props.submitting"
|
||||||
@click="emit('submit')"
|
@click="emit('submit')"
|
||||||
>
|
>
|
||||||
确认调价
|
确认调价
|
||||||
</a-button>
|
</Button>
|
||||||
<a-button @click="emit('close')">取消</a-button>
|
<Button @click="emit('close')">取消</Button>
|
||||||
</footer>
|
</footer>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { BatchScopeType } from '../types';
|
import type { BatchScopeType } from '../types';
|
||||||
|
import { Button, Select } from 'ant-design-vue';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
action: 'off' | 'on';
|
action: 'off' | 'on';
|
||||||
@@ -74,7 +75,7 @@ function setScopeProductIds(value: unknown) {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a-select
|
<Select
|
||||||
v-if="props.scopeType === 'category'"
|
v-if="props.scopeType === 'category'"
|
||||||
mode="multiple"
|
mode="multiple"
|
||||||
:value="props.scopeCategoryIds"
|
:value="props.scopeCategoryIds"
|
||||||
@@ -84,7 +85,7 @@ function setScopeProductIds(value: unknown) {
|
|||||||
@update:value="setScopeCategoryIds"
|
@update:value="setScopeCategoryIds"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<a-select
|
<Select
|
||||||
v-if="props.scopeType === 'manual'"
|
v-if="props.scopeType === 'manual'"
|
||||||
mode="multiple"
|
mode="multiple"
|
||||||
:value="props.scopeProductIds"
|
:value="props.scopeProductIds"
|
||||||
@@ -116,14 +117,15 @@ function setScopeProductIds(value: unknown) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer class="pbt-actions">
|
<footer class="pbt-actions">
|
||||||
<a-button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
:loading="props.submitting"
|
:loading="props.submitting"
|
||||||
@click="emit('submit')"
|
@click="emit('submit')"
|
||||||
>
|
>
|
||||||
确认执行
|
确认执行
|
||||||
</a-button>
|
</Button>
|
||||||
<a-button @click="emit('close')">取消</a-button>
|
<Button @click="emit('close')">取消</Button>
|
||||||
</footer>
|
</footer>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { Button, Checkbox, Input, Select, Space } from 'ant-design-vue';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
productIds: string[];
|
productIds: string[];
|
||||||
@@ -62,7 +64,7 @@ function setSyncStatus(value: boolean | string | undefined) {
|
|||||||
|
|
||||||
<div class="pbt-step">
|
<div class="pbt-step">
|
||||||
<div class="pbt-step-label"><span class="num">1</span> 源门店</div>
|
<div class="pbt-step-label"><span class="num">1</span> 源门店</div>
|
||||||
<a-input
|
<Input
|
||||||
:value="props.sourceStoreName"
|
:value="props.sourceStoreName"
|
||||||
disabled
|
disabled
|
||||||
class="pbt-select-narrow"
|
class="pbt-select-narrow"
|
||||||
@@ -71,7 +73,7 @@ function setSyncStatus(value: boolean | string | undefined) {
|
|||||||
|
|
||||||
<div class="pbt-step">
|
<div class="pbt-step">
|
||||||
<div class="pbt-step-label"><span class="num">2</span> 目标门店</div>
|
<div class="pbt-step-label"><span class="num">2</span> 目标门店</div>
|
||||||
<a-select
|
<Select
|
||||||
mode="multiple"
|
mode="multiple"
|
||||||
:value="props.targetStoreIds"
|
:value="props.targetStoreIds"
|
||||||
:options="props.targetStoreOptions"
|
:options="props.targetStoreOptions"
|
||||||
@@ -83,7 +85,7 @@ function setSyncStatus(value: boolean | string | undefined) {
|
|||||||
|
|
||||||
<div class="pbt-step">
|
<div class="pbt-step">
|
||||||
<div class="pbt-step-label"><span class="num">3</span> 同步商品</div>
|
<div class="pbt-step-label"><span class="num">3</span> 同步商品</div>
|
||||||
<a-select
|
<Select
|
||||||
mode="multiple"
|
mode="multiple"
|
||||||
:value="props.productIds"
|
:value="props.productIds"
|
||||||
:options="props.productOptions"
|
:options="props.productOptions"
|
||||||
@@ -95,28 +97,29 @@ function setSyncStatus(value: boolean | string | undefined) {
|
|||||||
|
|
||||||
<div class="pbt-step">
|
<div class="pbt-step">
|
||||||
<div class="pbt-step-label"><span class="num">4</span> 同步选项</div>
|
<div class="pbt-step-label"><span class="num">4</span> 同步选项</div>
|
||||||
<a-space>
|
<Space>
|
||||||
<a-checkbox :checked="props.syncPrice" @update:checked="setSyncPrice">
|
<Checkbox :checked="props.syncPrice" @update:checked="setSyncPrice">
|
||||||
价格
|
价格
|
||||||
</a-checkbox>
|
</Checkbox>
|
||||||
<a-checkbox :checked="props.syncStock" @update:checked="setSyncStock">
|
<Checkbox :checked="props.syncStock" @update:checked="setSyncStock">
|
||||||
库存
|
库存
|
||||||
</a-checkbox>
|
</Checkbox>
|
||||||
<a-checkbox :checked="props.syncStatus" @update:checked="setSyncStatus">
|
<Checkbox :checked="props.syncStatus" @update:checked="setSyncStatus">
|
||||||
状态
|
状态
|
||||||
</a-checkbox>
|
</Checkbox>
|
||||||
</a-space>
|
</Space>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer class="pbt-actions">
|
<footer class="pbt-actions">
|
||||||
<a-button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
:loading="props.submitting"
|
:loading="props.submitting"
|
||||||
@click="emit('submit')"
|
@click="emit('submit')"
|
||||||
>
|
>
|
||||||
确认同步
|
确认同步
|
||||||
</a-button>
|
</Button>
|
||||||
<a-button @click="emit('close')">取消</a-button>
|
<Button @click="emit('close')">取消</Button>
|
||||||
</footer>
|
</footer>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import type { BatchToolCard, BatchToolKey } from '../types';
|
import type { BatchToolCard, BatchToolKey } from '../types';
|
||||||
|
|
||||||
import { IconifyIcon } from '@vben/icons';
|
import { IconifyIcon } from '@vben/icons';
|
||||||
|
import { Button } from 'ant-design-vue';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
activeTool: BatchToolKey | null;
|
activeTool: BatchToolKey | null;
|
||||||
@@ -29,9 +30,10 @@ const emit = defineEmits<Emits>();
|
|||||||
</div>
|
</div>
|
||||||
<h3 class="pbt-card-name">{{ card.title }}</h3>
|
<h3 class="pbt-card-name">{{ card.title }}</h3>
|
||||||
<p class="pbt-card-desc">{{ card.description }}</p>
|
<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 ? '收起' : '开始操作' }}
|
{{ props.activeTool === card.key ? '收起' : '开始操作' }}
|
||||||
</a-button>
|
</Button>
|
||||||
</article>
|
</article>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { Select } from 'ant-design-vue';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
isStoreLoading: boolean;
|
isStoreLoading: boolean;
|
||||||
selectedStoreId: string;
|
selectedStoreId: string;
|
||||||
@@ -12,8 +14,13 @@ interface Emits {
|
|||||||
const props = defineProps<Props>();
|
const props = defineProps<Props>();
|
||||||
const emit = defineEmits<Emits>();
|
const emit = defineEmits<Emits>();
|
||||||
|
|
||||||
function setStore(value: string | undefined) {
|
function setStore(value: unknown) {
|
||||||
emit('update:selectedStoreId', value ?? '');
|
if (typeof value === 'string' || typeof value === 'number') {
|
||||||
|
emit('update:selectedStoreId', String(value));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit('update:selectedStoreId', '');
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -21,7 +28,7 @@ function setStore(value: string | undefined) {
|
|||||||
<div class="pbt-toolbar">
|
<div class="pbt-toolbar">
|
||||||
<div class="pbt-toolbar-main">
|
<div class="pbt-toolbar-main">
|
||||||
<span class="pbt-toolbar-label">门店</span>
|
<span class="pbt-toolbar-label">门店</span>
|
||||||
<a-select
|
<Select
|
||||||
class="pbt-toolbar-store"
|
class="pbt-toolbar-store"
|
||||||
:value="props.selectedStoreId"
|
:value="props.selectedStoreId"
|
||||||
:options="props.storeOptions"
|
:options="props.storeOptions"
|
||||||
@@ -33,3 +40,4 @@ function setStore(value: string | undefined) {
|
|||||||
<div class="pbt-toolbar-tip">选择门店后,工具仅作用于当前门店商品</div>
|
<div class="pbt-toolbar-tip">选择门店后,工具仅作用于当前门店商品</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user