fix: sku list
This commit is contained in:
@@ -160,7 +160,6 @@ export function useSkuFormSchema(
|
|||||||
fieldName: 'singleSkuList',
|
fieldName: 'singleSkuList',
|
||||||
label: '',
|
label: '',
|
||||||
component: 'Input',
|
component: 'Input',
|
||||||
componentProps: {},
|
|
||||||
dependencies: {
|
dependencies: {
|
||||||
triggerFields: ['specType'],
|
triggerFields: ['specType'],
|
||||||
// 当 specType 为 false(单规格)时显示
|
// 当 specType 为 false(单规格)时显示
|
||||||
@@ -172,7 +171,6 @@ export function useSkuFormSchema(
|
|||||||
fieldName: 'productAttributes',
|
fieldName: 'productAttributes',
|
||||||
label: '商品属性',
|
label: '商品属性',
|
||||||
component: 'Input',
|
component: 'Input',
|
||||||
componentProps: {},
|
|
||||||
dependencies: {
|
dependencies: {
|
||||||
triggerFields: ['specType'],
|
triggerFields: ['specType'],
|
||||||
// 当 specType 为 true(多规格)时显示
|
// 当 specType 为 true(多规格)时显示
|
||||||
@@ -184,7 +182,6 @@ export function useSkuFormSchema(
|
|||||||
fieldName: 'batchSkuList',
|
fieldName: 'batchSkuList',
|
||||||
label: '批量设置',
|
label: '批量设置',
|
||||||
component: 'Input',
|
component: 'Input',
|
||||||
componentProps: {},
|
|
||||||
dependencies: {
|
dependencies: {
|
||||||
triggerFields: ['specType'],
|
triggerFields: ['specType'],
|
||||||
// 当 specType 为 true(多规格)且 propertyList 有数据时显示,且非详情模式
|
// 当 specType 为 true(多规格)且 propertyList 有数据时显示,且非详情模式
|
||||||
@@ -197,7 +194,6 @@ export function useSkuFormSchema(
|
|||||||
fieldName: 'multiSkuList',
|
fieldName: 'multiSkuList',
|
||||||
label: '规格列表',
|
label: '规格列表',
|
||||||
component: 'Input',
|
component: 'Input',
|
||||||
componentProps: {},
|
|
||||||
dependencies: {
|
dependencies: {
|
||||||
triggerFields: ['specType'],
|
triggerFields: ['specType'],
|
||||||
// 当 specType 为 true(多规格)且 propertyList 有数据时显示
|
// 当 specType 为 true(多规格)且 propertyList 有数据时显示
|
||||||
|
|||||||
@@ -313,67 +313,69 @@ onMounted(async () => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ProductPropertyAddFormModal :property-list="propertyList" />
|
<div>
|
||||||
|
<ProductPropertyAddFormModal :property-list="propertyList" />
|
||||||
|
|
||||||
<Page auto-content-height>
|
<Page auto-content-height>
|
||||||
<ContentWrap class="h-full w-full pb-8">
|
<ContentWrap class="h-full w-full pb-8">
|
||||||
<template #extra>
|
<template #extra>
|
||||||
<Button type="primary" @click="onSubmit">保存</Button>
|
<Button type="primary" @click="onSubmit">保存</Button>
|
||||||
</template>
|
</template>
|
||||||
<Tabs v-model:active-key="activeTabName">
|
<Tabs v-model:active-key="activeTabName">
|
||||||
<Tabs.TabPane tab="基础设置" key="info">
|
<Tabs.TabPane tab="基础设置" key="info">
|
||||||
<InfoForm class="w-3/5" />
|
<InfoForm class="w-3/5" />
|
||||||
</Tabs.TabPane>
|
</Tabs.TabPane>
|
||||||
<Tabs.TabPane tab="价格库存" key="sku">
|
<Tabs.TabPane tab="价格库存" key="sku">
|
||||||
<SkuForm class="w-full">
|
<SkuForm class="w-full">
|
||||||
<template #singleSkuList>
|
<template #singleSkuList>
|
||||||
<SkuList
|
<SkuList
|
||||||
ref="skuListRef"
|
ref="skuListRef"
|
||||||
:prop-form-data="formData"
|
:prop-form-data="formData"
|
||||||
:property-list="propertyList"
|
|
||||||
:rule-config="ruleConfig"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
<template #productAttributes>
|
|
||||||
<div>
|
|
||||||
<Button class="mb-10px mr-15px" @click="openPropertyAddForm">
|
|
||||||
添加属性
|
|
||||||
</Button>
|
|
||||||
<ProductAttributes
|
|
||||||
:is-detail="isDetail"
|
|
||||||
:property-list="propertyList"
|
:property-list="propertyList"
|
||||||
@success="generateSkus"
|
:rule-config="ruleConfig"
|
||||||
/>
|
/>
|
||||||
</div>
|
</template>
|
||||||
</template>
|
<template #productAttributes>
|
||||||
<template #batchSkuList>
|
<div>
|
||||||
<SkuList
|
<Button class="mb-10px mr-15px" @click="openPropertyAddForm">
|
||||||
:is-batch="true"
|
添加属性
|
||||||
:prop-form-data="formData"
|
</Button>
|
||||||
:property-list="propertyList"
|
<ProductAttributes
|
||||||
/>
|
:is-detail="isDetail"
|
||||||
</template>
|
:property-list="propertyList"
|
||||||
<template #multiSkuList>
|
@success="generateSkus"
|
||||||
<SkuList
|
/>
|
||||||
ref="skuListRef"
|
</div>
|
||||||
:is-detail="isDetail"
|
</template>
|
||||||
:prop-form-data="formData"
|
<template #batchSkuList>
|
||||||
:property-list="propertyList"
|
<SkuList
|
||||||
:rule-config="ruleConfig"
|
:is-batch="true"
|
||||||
/>
|
:prop-form-data="formData"
|
||||||
</template>
|
:property-list="propertyList"
|
||||||
</SkuForm>
|
/>
|
||||||
</Tabs.TabPane>
|
</template>
|
||||||
<Tabs.TabPane tab="物流设置" key="delivery">
|
<template #multiSkuList>
|
||||||
<DeliveryForm class="w-3/5" />
|
<SkuList
|
||||||
</Tabs.TabPane>
|
ref="skuListRef"
|
||||||
<Tabs.TabPane tab="商品详情" key="description">
|
:is-detail="isDetail"
|
||||||
<DescriptionForm class="w-3/5" />
|
:prop-form-data="formData"
|
||||||
</Tabs.TabPane>
|
:property-list="propertyList"
|
||||||
<Tabs.TabPane tab="其它设置" key="other">
|
:rule-config="ruleConfig"
|
||||||
<OtherForm class="w-3/5" />
|
/>
|
||||||
</Tabs.TabPane>
|
</template>
|
||||||
</Tabs>
|
</SkuForm>
|
||||||
</ContentWrap>
|
</Tabs.TabPane>
|
||||||
</Page>
|
<Tabs.TabPane tab="物流设置" key="delivery">
|
||||||
|
<DeliveryForm class="w-3/5" />
|
||||||
|
</Tabs.TabPane>
|
||||||
|
<Tabs.TabPane tab="商品详情" key="description">
|
||||||
|
<DescriptionForm class="w-3/5" />
|
||||||
|
</Tabs.TabPane>
|
||||||
|
<Tabs.TabPane tab="其它设置" key="other">
|
||||||
|
<OtherForm class="w-3/5" />
|
||||||
|
</Tabs.TabPane>
|
||||||
|
</Tabs>
|
||||||
|
</ContentWrap>
|
||||||
|
</Page>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||||
import type { MallSpuApi } from '#/api/mall/product/spu';
|
import type { MallSpuApi } from '#/api/mall/product/spu';
|
||||||
|
|
||||||
export interface PropertyAndValues {
|
export interface PropertyAndValues {
|
||||||
@@ -39,9 +40,7 @@ const getPropertyList = (spu: MallSpuApi.Spu): PropertyAndValues[] => {
|
|||||||
// 添加属性
|
// 添加属性
|
||||||
if (!properties?.some((item) => item.id === propertyId)) {
|
if (!properties?.some((item) => item.id === propertyId)) {
|
||||||
properties.push({
|
properties.push({
|
||||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
||||||
id: propertyId!,
|
id: propertyId!,
|
||||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
||||||
name: propertyName!,
|
name: propertyName!,
|
||||||
values: [],
|
values: [],
|
||||||
});
|
});
|
||||||
@@ -51,7 +50,6 @@ const getPropertyList = (spu: MallSpuApi.Spu): PropertyAndValues[] => {
|
|||||||
if (
|
if (
|
||||||
!properties[index]?.values?.some((value) => value.id === valueId)
|
!properties[index]?.values?.some((value) => value.id === valueId)
|
||||||
) {
|
) {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
||||||
properties[index]?.values?.push({ id: valueId!, name: valueName! });
|
properties[index]?.values?.push({ id: valueId!, name: valueName! });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ interface InputRefItem {
|
|||||||
|
|
||||||
const inputRef = ref<InputRefItem[]>([]); // 标签输入框Ref
|
const inputRef = ref<InputRefItem[]>([]); // 标签输入框Ref
|
||||||
/** 解决 ref 在 v-for 中的获取问题*/
|
/** 解决 ref 在 v-for 中的获取问题*/
|
||||||
const setInputRef = (el: any) => {
|
function setInputRef(el: any) {
|
||||||
if (el === null || el === undefined) return;
|
if (el === null || el === undefined) return;
|
||||||
// 如果不存在 id 相同的元素才添加
|
// 如果不存在 id 相同的元素才添加
|
||||||
if (
|
if (
|
||||||
@@ -58,7 +58,7 @@ const setInputRef = (el: any) => {
|
|||||||
) {
|
) {
|
||||||
inputRef.value.push(el);
|
inputRef.value.push(el);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
const attributeList = ref<PropertyAndValues[]>([]); // 商品属性列表
|
const attributeList = ref<PropertyAndValues[]>([]); // 商品属性列表
|
||||||
const attributeOptions = ref<MallPropertyApi.PropertyValue[]>([]); // 商品属性值下拉框
|
const attributeOptions = ref<MallPropertyApi.PropertyValue[]>([]); // 商品属性值下拉框
|
||||||
|
|
||||||
@@ -75,26 +75,26 @@ watch(
|
|||||||
);
|
);
|
||||||
|
|
||||||
/** 删除属性值*/
|
/** 删除属性值*/
|
||||||
const handleCloseValue = (index: number, valueIndex: number) => {
|
function handleCloseValue(index: number, valueIndex: number) {
|
||||||
attributeList.value?.[index]?.values?.splice(valueIndex, 1);
|
attributeList.value?.[index]?.values?.splice(valueIndex, 1);
|
||||||
};
|
}
|
||||||
|
|
||||||
/** 删除属性*/
|
/** 删除属性*/
|
||||||
const handleCloseProperty = (index: number) => {
|
function handleCloseProperty(index: number) {
|
||||||
attributeList.value?.splice(index, 1);
|
attributeList.value?.splice(index, 1);
|
||||||
emit('success', attributeList.value);
|
emit('success', attributeList.value);
|
||||||
};
|
}
|
||||||
|
|
||||||
/** 显示输入框并获取焦点 */
|
/** 显示输入框并获取焦点 */
|
||||||
const showInput = async (index: number) => {
|
async function showInput(index: number) {
|
||||||
attributeIndex.value = index;
|
attributeIndex.value = index;
|
||||||
inputRef.value?.[index]?.focus();
|
inputRef.value?.[index]?.focus();
|
||||||
// 获取属性下拉选项
|
// 获取属性下拉选项
|
||||||
await getAttributeOptions(attributeList.value?.[index]?.id!);
|
await getAttributeOptions(attributeList.value?.[index]?.id!);
|
||||||
};
|
}
|
||||||
|
|
||||||
// 定义 success 事件,用于操作成功后的回调
|
// 定义 success 事件,用于操作成功后的回调
|
||||||
const handleInputConfirm = async (index: number, propertyId: number) => {
|
async function handleInputConfirm(index: number, propertyId: number) {
|
||||||
// 从数组中取最后一个输入的值(tags 模式下 inputValue 是数组)
|
// 从数组中取最后一个输入的值(tags 模式下 inputValue 是数组)
|
||||||
const currentValue = inputValue.value?.[inputValue.value.length - 1]?.trim();
|
const currentValue = inputValue.value?.[inputValue.value.length - 1]?.trim();
|
||||||
|
|
||||||
@@ -144,12 +144,12 @@ const handleInputConfirm = async (index: number, propertyId: number) => {
|
|||||||
}
|
}
|
||||||
attributeIndex.value = null;
|
attributeIndex.value = null;
|
||||||
inputValue.value = [];
|
inputValue.value = [];
|
||||||
};
|
}
|
||||||
|
|
||||||
/** 获取商品属性下拉选项 */
|
/** 获取商品属性下拉选项 */
|
||||||
const getAttributeOptions = async (propertyId: number) => {
|
async function getAttributeOptions(propertyId: number) {
|
||||||
attributeOptions.value = await getPropertyValueSimpleList(propertyId);
|
attributeOptions.value = await getPropertyValueSimpleList(propertyId);
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ const [Modal, modalApi] = useVbenModal({
|
|||||||
name,
|
name,
|
||||||
values: [],
|
values: [],
|
||||||
});
|
});
|
||||||
message.success($t('common.createSuccess'));
|
message.success($t('ui.actionMessage.operationSuccess'));
|
||||||
await modalApi.close();
|
await modalApi.close();
|
||||||
emit('success');
|
emit('success');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -60,15 +60,15 @@ const skuList = ref<MallSpuApi.Sku[]>([
|
|||||||
]); // 批量添加时的临时数据
|
]); // 批量添加时的临时数据
|
||||||
|
|
||||||
/** 批量添加 */
|
/** 批量添加 */
|
||||||
const batchAdd = () => {
|
function batchAdd() {
|
||||||
validateProperty();
|
validateProperty();
|
||||||
formData.value!.skus!.forEach((item: MallSpuApi.Sku) => {
|
formData.value!.skus!.forEach((item: MallSpuApi.Sku) => {
|
||||||
copyValueToTarget(item, skuList.value[0]);
|
copyValueToTarget(item, skuList.value[0]);
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
/** 校验商品属性属性值 */
|
/** 校验商品属性属性值 */
|
||||||
const validateProperty = () => {
|
function validateProperty() {
|
||||||
// 校验商品属性属性值是否为空,有一个为空都不给过
|
// 校验商品属性属性值是否为空,有一个为空都不给过
|
||||||
const warningInfo = '存在属性属性值为空,请先检查完善属性值后重试!!!';
|
const warningInfo = '存在属性属性值为空,请先检查完善属性值后重试!!!';
|
||||||
for (const item of props.propertyList as PropertyAndValues[]) {
|
for (const item of props.propertyList as PropertyAndValues[]) {
|
||||||
@@ -77,24 +77,24 @@ const validateProperty = () => {
|
|||||||
throw new Error(warningInfo);
|
throw new Error(warningInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
/** 删除 sku */
|
/** 删除 sku */
|
||||||
const deleteSku = (row: MallSpuApi.Sku) => {
|
function deleteSku(row: MallSpuApi.Sku) {
|
||||||
const index = formData.value!.skus!.findIndex(
|
const index = formData.value!.skus!.findIndex(
|
||||||
// 直接把列表转成字符串比较
|
// 直接把列表转成字符串比较
|
||||||
(sku: MallSpuApi.Sku) =>
|
(sku: MallSpuApi.Sku) =>
|
||||||
JSON.stringify(sku.properties) === JSON.stringify(row.properties),
|
JSON.stringify(sku.properties) === JSON.stringify(row.properties),
|
||||||
);
|
);
|
||||||
formData.value!.skus!.splice(index, 1);
|
formData.value!.skus!.splice(index, 1);
|
||||||
};
|
}
|
||||||
|
|
||||||
const tableHeaders = ref<{ label: string; prop: string }[]>([]); // 多属性表头
|
const tableHeaders = ref<{ label: string; prop: string }[]>([]); // 多属性表头
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存时,每个商品规格的表单要校验下。例如说,销售金额最低是 0.01 这种。
|
* 保存时,每个商品规格的表单要校验下。例如说,销售金额最低是 0.01 这种。
|
||||||
*/
|
*/
|
||||||
const validateSku = () => {
|
function validateSku() {
|
||||||
validateProperty();
|
validateProperty();
|
||||||
let warningInfo = '请检查商品各行相关属性配置,';
|
let warningInfo = '请检查商品各行相关属性配置,';
|
||||||
let validate = true; // 默认通过
|
let validate = true; // 默认通过
|
||||||
@@ -114,9 +114,9 @@ const validateSku = () => {
|
|||||||
throw new Error(warningInfo);
|
throw new Error(warningInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
const getValue = (obj: any, arg: string): unknown => {
|
function getValue(obj: any, arg: string): unknown {
|
||||||
const keys = arg.split('.');
|
const keys = arg.split('.');
|
||||||
let value: any = obj;
|
let value: any = obj;
|
||||||
for (const key of keys) {
|
for (const key of keys) {
|
||||||
@@ -128,15 +128,15 @@ const getValue = (obj: any, arg: string): unknown => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 选择时触发
|
* 选择时触发
|
||||||
* @param records 传递过来的选中的 sku 是一个数组
|
* @param records 传递过来的选中的 sku 是一个数组
|
||||||
*/
|
*/
|
||||||
const handleSelectionChange = ({ records }: { records: MallSpuApi.Sku[] }) => {
|
function handleSelectionChange({ records }: { records: MallSpuApi.Sku[] }) {
|
||||||
emit('selectionChange', records);
|
emit('selectionChange', records);
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将传进来的值赋值给 skuList
|
* 将传进来的值赋值给 skuList
|
||||||
@@ -154,7 +154,7 @@ watch(
|
|||||||
);
|
);
|
||||||
|
|
||||||
/** 生成表数据 */
|
/** 生成表数据 */
|
||||||
const generateTableData = (propertyList: PropertyAndValues[]) => {
|
function generateTableData(propertyList: PropertyAndValues[]) {
|
||||||
// 构建数据结构
|
// 构建数据结构
|
||||||
const propertyValues = propertyList.map((item: PropertyAndValues) =>
|
const propertyValues = propertyList.map((item: PropertyAndValues) =>
|
||||||
(item.values || []).map((v: { id: number; name: string }) => ({
|
(item.values || []).map((v: { id: number; name: string }) => ({
|
||||||
@@ -194,12 +194,12 @@ const generateTableData = (propertyList: PropertyAndValues[]) => {
|
|||||||
}
|
}
|
||||||
formData.value!.skus!.push(row);
|
formData.value!.skus!.push(row);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成 skus 前置校验
|
* 生成 skus 前置校验
|
||||||
*/
|
*/
|
||||||
const validateData = (propertyList: PropertyAndValues[]): boolean => {
|
function validateData(propertyList: PropertyAndValues[]): boolean {
|
||||||
const skuPropertyIds: number[] = [];
|
const skuPropertyIds: number[] = [];
|
||||||
formData.value!.skus!.forEach((sku: MallSpuApi.Sku) =>
|
formData.value!.skus!.forEach((sku: MallSpuApi.Sku) =>
|
||||||
sku.properties
|
sku.properties
|
||||||
@@ -212,12 +212,12 @@ const validateData = (propertyList: PropertyAndValues[]): boolean => {
|
|||||||
);
|
);
|
||||||
const propertyIds = propertyList.map((item: PropertyAndValues) => item.id);
|
const propertyIds = propertyList.map((item: PropertyAndValues) => item.id);
|
||||||
return skuPropertyIds.length === propertyIds.length;
|
return skuPropertyIds.length === propertyIds.length;
|
||||||
};
|
}
|
||||||
|
|
||||||
/** 构建所有排列组合 */
|
/** 构建所有排列组合 */
|
||||||
const build = (
|
function build(
|
||||||
propertyValuesList: MallSpuApi.Property[][],
|
propertyValuesList: MallSpuApi.Property[][],
|
||||||
): (MallSpuApi.Property | MallSpuApi.Property[])[] => {
|
): (MallSpuApi.Property | MallSpuApi.Property[])[] {
|
||||||
if (propertyValuesList.length === 0) {
|
if (propertyValuesList.length === 0) {
|
||||||
return [];
|
return [];
|
||||||
} else if (propertyValuesList.length === 1) {
|
} else if (propertyValuesList.length === 1) {
|
||||||
@@ -240,7 +240,7 @@ const build = (
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
/** 监听属性列表,生成相关参数和表头 */
|
/** 监听属性列表,生成相关参数和表头 */
|
||||||
watch(
|
watch(
|
||||||
@@ -298,307 +298,315 @@ watch(
|
|||||||
|
|
||||||
const activitySkuListRef = ref();
|
const activitySkuListRef = ref();
|
||||||
|
|
||||||
const getSkuTableRef = () => {
|
function getSkuTableRef() {
|
||||||
return activitySkuListRef.value;
|
return activitySkuListRef.value;
|
||||||
};
|
}
|
||||||
|
|
||||||
// 暴露出生成 sku 方法,给添加属性成功时调用
|
// 暴露出生成 sku 方法,给添加属性成功时调用
|
||||||
defineExpose({ generateTableData, validateSku, getSkuTableRef });
|
defineExpose({ generateTableData, validateSku, getSkuTableRef });
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<!-- 情况一:添加/修改 -->
|
<div>
|
||||||
<VxeTable
|
<!-- 情况一:添加/修改 -->
|
||||||
v-if="!isDetail && !isActivityComponent"
|
<VxeTable
|
||||||
:data="isBatch ? skuList : formData?.skus || []"
|
v-if="!isDetail && !isActivityComponent"
|
||||||
border
|
:data="isBatch ? skuList : formData?.skus || []"
|
||||||
max-height="500"
|
border
|
||||||
size="small"
|
max-height="500"
|
||||||
class="w-full"
|
size="small"
|
||||||
>
|
class="w-full"
|
||||||
<VxeColumn align="center" title="图片" min-width="80">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<ImageUpload
|
|
||||||
v-model:value="row.picUrl"
|
|
||||||
:max-number="1"
|
|
||||||
:max-size="2"
|
|
||||||
:show-description="false"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
</VxeColumn>
|
|
||||||
<template v-if="formData?.specType && !isBatch">
|
|
||||||
<!-- 根据商品属性动态添加 -->
|
|
||||||
<VxeColumn
|
|
||||||
v-for="(item, index) in tableHeaders"
|
|
||||||
:key="index"
|
|
||||||
:title="item.label"
|
|
||||||
align="center"
|
|
||||||
min-width="120"
|
|
||||||
>
|
|
||||||
<template #default="{ row }">
|
|
||||||
<span class="font-bold text-[#40aaff]">
|
|
||||||
{{ row.properties?.[index]?.valueName }}
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
</VxeColumn>
|
|
||||||
</template>
|
|
||||||
<VxeColumn align="center" title="商品条码" min-width="168">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<Input v-model:value="row.barCode" class="w-full" />
|
|
||||||
</template>
|
|
||||||
</VxeColumn>
|
|
||||||
<VxeColumn align="center" title="销售价" min-width="168">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<InputNumber
|
|
||||||
v-model:value="row.price"
|
|
||||||
:min="0"
|
|
||||||
:precision="2"
|
|
||||||
:step="0.1"
|
|
||||||
class="w-full"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
</VxeColumn>
|
|
||||||
<VxeColumn align="center" title="市场价" min-width="168">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<InputNumber
|
|
||||||
v-model:value="row.marketPrice"
|
|
||||||
:min="0"
|
|
||||||
:precision="2"
|
|
||||||
:step="0.1"
|
|
||||||
class="w-full"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
</VxeColumn>
|
|
||||||
<VxeColumn align="center" title="成本价" min-width="168">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<InputNumber
|
|
||||||
v-model:value="row.costPrice"
|
|
||||||
:min="0"
|
|
||||||
:precision="2"
|
|
||||||
:step="0.1"
|
|
||||||
class="w-full"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
</VxeColumn>
|
|
||||||
<VxeColumn align="center" title="库存" min-width="168">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<InputNumber v-model:value="row.stock" :min="0" class="w-full" />
|
|
||||||
</template>
|
|
||||||
</VxeColumn>
|
|
||||||
<VxeColumn align="center" title="重量(kg)" min-width="168">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<InputNumber
|
|
||||||
v-model:value="row.weight"
|
|
||||||
:min="0"
|
|
||||||
:precision="2"
|
|
||||||
:step="0.1"
|
|
||||||
class="w-full"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
</VxeColumn>
|
|
||||||
<VxeColumn align="center" title="体积(m^3)" min-width="168">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<InputNumber
|
|
||||||
v-model:value="row.volume"
|
|
||||||
:min="0"
|
|
||||||
:precision="2"
|
|
||||||
:step="0.1"
|
|
||||||
class="w-full"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
</VxeColumn>
|
|
||||||
<template v-if="formData?.subCommissionType">
|
|
||||||
<VxeColumn align="center" title="一级返佣(元)" min-width="168">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<InputNumber
|
|
||||||
v-model:value="row.firstBrokeragePrice"
|
|
||||||
:min="0"
|
|
||||||
:precision="2"
|
|
||||||
:step="0.1"
|
|
||||||
class="w-full"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
</VxeColumn>
|
|
||||||
<VxeColumn align="center" title="二级返佣(元)" min-width="168">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<InputNumber
|
|
||||||
v-model:value="row.secondBrokeragePrice"
|
|
||||||
:min="0"
|
|
||||||
:precision="2"
|
|
||||||
:step="0.1"
|
|
||||||
class="w-full"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
</VxeColumn>
|
|
||||||
</template>
|
|
||||||
<VxeColumn
|
|
||||||
v-if="formData?.specType"
|
|
||||||
align="center"
|
|
||||||
fixed="right"
|
|
||||||
title="操作"
|
|
||||||
width="100"
|
|
||||||
>
|
>
|
||||||
<template #default="{ row }">
|
<VxeColumn align="center" title="图片" min-width="120">
|
||||||
<Button v-if="isBatch" type="link" size="small" @click="batchAdd">
|
<template #default="{ row }">
|
||||||
批量添加
|
<ImageUpload
|
||||||
</Button>
|
v-model:value="row.picUrl"
|
||||||
<Button v-else type="link" size="small" danger @click="deleteSku(row)">
|
:max-number="1"
|
||||||
删除
|
:max-size="2"
|
||||||
</Button>
|
:show-description="false"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</VxeColumn>
|
||||||
|
<template v-if="formData?.specType && !isBatch">
|
||||||
|
<!-- 根据商品属性动态添加 -->
|
||||||
|
<VxeColumn
|
||||||
|
v-for="(item, index) in tableHeaders"
|
||||||
|
:key="index"
|
||||||
|
:title="item.label"
|
||||||
|
align="center"
|
||||||
|
min-width="120"
|
||||||
|
>
|
||||||
|
<template #default="{ row }">
|
||||||
|
<span class="font-bold text-[#40aaff]">
|
||||||
|
{{ row.properties?.[index]?.valueName }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</VxeColumn>
|
||||||
</template>
|
</template>
|
||||||
</VxeColumn>
|
<VxeColumn align="center" title="商品条码" min-width="168">
|
||||||
</VxeTable>
|
<template #default="{ row }">
|
||||||
|
<Input v-model:value="row.barCode" class="w-full" />
|
||||||
<!-- 情况二:详情 -->
|
</template>
|
||||||
<VxeTable
|
</VxeColumn>
|
||||||
v-if="isDetail"
|
<VxeColumn align="center" title="销售价" min-width="168">
|
||||||
ref="activitySkuListRef"
|
<template #default="{ row }">
|
||||||
:data="formData?.skus || []"
|
<InputNumber
|
||||||
border
|
v-model:value="row.price"
|
||||||
max-height="500"
|
:min="0"
|
||||||
size="small"
|
:precision="2"
|
||||||
class="w-full"
|
:step="0.1"
|
||||||
:checkbox-config="isComponent ? { reserve: true } : undefined"
|
class="w-full"
|
||||||
@checkbox-change="handleSelectionChange"
|
/>
|
||||||
@checkbox-all="handleSelectionChange"
|
</template>
|
||||||
>
|
</VxeColumn>
|
||||||
<VxeColumn v-if="isComponent" type="checkbox" width="45" />
|
<VxeColumn align="center" title="市场价" min-width="168">
|
||||||
<VxeColumn align="center" title="图片" min-width="80">
|
<template #default="{ row }">
|
||||||
<template #default="{ row }">
|
<InputNumber
|
||||||
<Image
|
v-model:value="row.marketPrice"
|
||||||
v-if="row.picUrl"
|
:min="0"
|
||||||
:src="row.picUrl"
|
:precision="2"
|
||||||
class="h-[50px] w-[50px] cursor-pointer"
|
:step="0.1"
|
||||||
:preview="true"
|
class="w-full"
|
||||||
/>
|
/>
|
||||||
|
</template>
|
||||||
|
</VxeColumn>
|
||||||
|
<VxeColumn align="center" title="成本价" min-width="168">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<InputNumber
|
||||||
|
v-model:value="row.costPrice"
|
||||||
|
:min="0"
|
||||||
|
:precision="2"
|
||||||
|
:step="0.1"
|
||||||
|
class="w-full"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</VxeColumn>
|
||||||
|
<VxeColumn align="center" title="库存" min-width="168">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<InputNumber v-model:value="row.stock" :min="0" class="w-full" />
|
||||||
|
</template>
|
||||||
|
</VxeColumn>
|
||||||
|
<VxeColumn align="center" title="重量(kg)" min-width="168">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<InputNumber
|
||||||
|
v-model:value="row.weight"
|
||||||
|
:min="0"
|
||||||
|
:precision="2"
|
||||||
|
:step="0.1"
|
||||||
|
class="w-full"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</VxeColumn>
|
||||||
|
<VxeColumn align="center" title="体积(m^3)" min-width="168">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<InputNumber
|
||||||
|
v-model:value="row.volume"
|
||||||
|
:min="0"
|
||||||
|
:precision="2"
|
||||||
|
:step="0.1"
|
||||||
|
class="w-full"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</VxeColumn>
|
||||||
|
<template v-if="formData?.subCommissionType">
|
||||||
|
<VxeColumn align="center" title="一级返佣(元)" min-width="168">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<InputNumber
|
||||||
|
v-model:value="row.firstBrokeragePrice"
|
||||||
|
:min="0"
|
||||||
|
:precision="2"
|
||||||
|
:step="0.1"
|
||||||
|
class="w-full"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</VxeColumn>
|
||||||
|
<VxeColumn align="center" title="二级返佣(元)" min-width="168">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<InputNumber
|
||||||
|
v-model:value="row.secondBrokeragePrice"
|
||||||
|
:min="0"
|
||||||
|
:precision="2"
|
||||||
|
:step="0.1"
|
||||||
|
class="w-full"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</VxeColumn>
|
||||||
</template>
|
</template>
|
||||||
</VxeColumn>
|
|
||||||
<template v-if="formData?.specType && !isBatch">
|
|
||||||
<!-- 根据商品属性动态添加 -->
|
|
||||||
<VxeColumn
|
<VxeColumn
|
||||||
v-for="(item, index) in tableHeaders"
|
v-if="formData?.specType"
|
||||||
:key="index"
|
|
||||||
:title="item.label"
|
|
||||||
align="center"
|
align="center"
|
||||||
min-width="80"
|
fixed="right"
|
||||||
|
title="操作"
|
||||||
|
width="100"
|
||||||
>
|
>
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<span class="font-bold text-[#40aaff]">
|
<Button v-if="isBatch" type="link" size="small" @click="batchAdd">
|
||||||
{{ row.properties?.[index]?.valueName }}
|
批量添加
|
||||||
</span>
|
</Button>
|
||||||
|
<Button
|
||||||
|
v-else
|
||||||
|
type="link"
|
||||||
|
size="small"
|
||||||
|
danger
|
||||||
|
@click="deleteSku(row)"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</Button>
|
||||||
</template>
|
</template>
|
||||||
</VxeColumn>
|
</VxeColumn>
|
||||||
</template>
|
</VxeTable>
|
||||||
<VxeColumn align="center" title="商品条码" min-width="100">
|
|
||||||
<template #default="{ row }">
|
|
||||||
{{ row.barCode }}
|
|
||||||
</template>
|
|
||||||
</VxeColumn>
|
|
||||||
<VxeColumn align="center" title="销售价(元)" min-width="80">
|
|
||||||
<template #default="{ row }">
|
|
||||||
{{ row.price }}
|
|
||||||
</template>
|
|
||||||
</VxeColumn>
|
|
||||||
<VxeColumn align="center" title="市场价(元)" min-width="80">
|
|
||||||
<template #default="{ row }">
|
|
||||||
{{ row.marketPrice }}
|
|
||||||
</template>
|
|
||||||
</VxeColumn>
|
|
||||||
<VxeColumn align="center" title="成本价(元)" min-width="80">
|
|
||||||
<template #default="{ row }">
|
|
||||||
{{ row.costPrice }}
|
|
||||||
</template>
|
|
||||||
</VxeColumn>
|
|
||||||
<VxeColumn align="center" title="库存" min-width="80">
|
|
||||||
<template #default="{ row }">
|
|
||||||
{{ row.stock }}
|
|
||||||
</template>
|
|
||||||
</VxeColumn>
|
|
||||||
<VxeColumn align="center" title="重量(kg)" min-width="80">
|
|
||||||
<template #default="{ row }">
|
|
||||||
{{ row.weight }}
|
|
||||||
</template>
|
|
||||||
</VxeColumn>
|
|
||||||
<VxeColumn align="center" title="体积(m^3)" min-width="80">
|
|
||||||
<template #default="{ row }">
|
|
||||||
{{ row.volume }}
|
|
||||||
</template>
|
|
||||||
</VxeColumn>
|
|
||||||
<template v-if="formData?.subCommissionType">
|
|
||||||
<VxeColumn align="center" title="一级返佣(元)" min-width="80">
|
|
||||||
<template #default="{ row }">
|
|
||||||
{{ row.firstBrokeragePrice }}
|
|
||||||
</template>
|
|
||||||
</VxeColumn>
|
|
||||||
<VxeColumn align="center" title="二级返佣(元)" min-width="80">
|
|
||||||
<template #default="{ row }">
|
|
||||||
{{ row.secondBrokeragePrice }}
|
|
||||||
</template>
|
|
||||||
</VxeColumn>
|
|
||||||
</template>
|
|
||||||
</VxeTable>
|
|
||||||
|
|
||||||
<!-- 情况三:作为活动组件 -->
|
<!-- 情况二:详情 -->
|
||||||
<VxeTable
|
<VxeTable
|
||||||
v-if="isActivityComponent"
|
v-if="isDetail"
|
||||||
:data="formData?.skus || []"
|
ref="activitySkuListRef"
|
||||||
border
|
:data="formData?.skus || []"
|
||||||
max-height="500"
|
border
|
||||||
size="small"
|
max-height="500"
|
||||||
class="w-full"
|
size="small"
|
||||||
>
|
class="w-full"
|
||||||
<VxeColumn v-if="isComponent" type="checkbox" width="45" />
|
:checkbox-config="isComponent ? { reserve: true } : undefined"
|
||||||
<VxeColumn align="center" title="图片" min-width="80">
|
@checkbox-change="handleSelectionChange"
|
||||||
<template #default="{ row }">
|
@checkbox-all="handleSelectionChange"
|
||||||
<Image
|
>
|
||||||
:src="row.picUrl"
|
<VxeColumn v-if="isComponent" type="checkbox" width="45" />
|
||||||
class="h-[60px] w-[60px] cursor-pointer"
|
<VxeColumn align="center" title="图片" min-width="120">
|
||||||
:preview="true"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
</VxeColumn>
|
|
||||||
<template v-if="formData?.specType">
|
|
||||||
<!-- 根据商品属性动态添加 -->
|
|
||||||
<VxeColumn
|
|
||||||
v-for="(item, index) in tableHeaders"
|
|
||||||
:key="index"
|
|
||||||
:title="item.label"
|
|
||||||
align="center"
|
|
||||||
min-width="80"
|
|
||||||
>
|
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<span class="font-bold text-[#40aaff]">
|
<Image
|
||||||
{{ row.properties?.[index]?.valueName }}
|
v-if="row.picUrl"
|
||||||
</span>
|
:src="row.picUrl"
|
||||||
|
class="h-[50px] w-[50px] cursor-pointer"
|
||||||
|
:preview="true"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</VxeColumn>
|
</VxeColumn>
|
||||||
</template>
|
<template v-if="formData?.specType && !isBatch">
|
||||||
<VxeColumn align="center" title="商品条码" min-width="100">
|
<!-- 根据商品属性动态添加 -->
|
||||||
<template #default="{ row }">
|
<VxeColumn
|
||||||
{{ row.barCode }}
|
v-for="(item, index) in tableHeaders"
|
||||||
|
:key="index"
|
||||||
|
:title="item.label"
|
||||||
|
align="center"
|
||||||
|
min-width="80"
|
||||||
|
>
|
||||||
|
<template #default="{ row }">
|
||||||
|
<span class="font-bold text-[#40aaff]">
|
||||||
|
{{ row.properties?.[index]?.valueName }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</VxeColumn>
|
||||||
</template>
|
</template>
|
||||||
</VxeColumn>
|
<VxeColumn align="center" title="商品条码" min-width="100">
|
||||||
<VxeColumn align="center" title="销售价(元)" min-width="80">
|
<template #default="{ row }">
|
||||||
<template #default="{ row }">
|
{{ row.barCode }}
|
||||||
{{ formatToFraction(row.price) }}
|
</template>
|
||||||
|
</VxeColumn>
|
||||||
|
<VxeColumn align="center" title="销售价(元)" min-width="80">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ row.price }}
|
||||||
|
</template>
|
||||||
|
</VxeColumn>
|
||||||
|
<VxeColumn align="center" title="市场价(元)" min-width="80">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ row.marketPrice }}
|
||||||
|
</template>
|
||||||
|
</VxeColumn>
|
||||||
|
<VxeColumn align="center" title="成本价(元)" min-width="80">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ row.costPrice }}
|
||||||
|
</template>
|
||||||
|
</VxeColumn>
|
||||||
|
<VxeColumn align="center" title="库存" min-width="80">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ row.stock }}
|
||||||
|
</template>
|
||||||
|
</VxeColumn>
|
||||||
|
<VxeColumn align="center" title="重量(kg)" min-width="80">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ row.weight }}
|
||||||
|
</template>
|
||||||
|
</VxeColumn>
|
||||||
|
<VxeColumn align="center" title="体积(m^3)" min-width="80">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ row.volume }}
|
||||||
|
</template>
|
||||||
|
</VxeColumn>
|
||||||
|
<template v-if="formData?.subCommissionType">
|
||||||
|
<VxeColumn align="center" title="一级返佣(元)" min-width="80">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ row.firstBrokeragePrice }}
|
||||||
|
</template>
|
||||||
|
</VxeColumn>
|
||||||
|
<VxeColumn align="center" title="二级返佣(元)" min-width="80">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ row.secondBrokeragePrice }}
|
||||||
|
</template>
|
||||||
|
</VxeColumn>
|
||||||
</template>
|
</template>
|
||||||
</VxeColumn>
|
</VxeTable>
|
||||||
<VxeColumn align="center" title="市场价(元)" min-width="80">
|
|
||||||
<template #default="{ row }">
|
<!-- 情况三:作为活动组件 -->
|
||||||
{{ formatToFraction(row.marketPrice) }}
|
<VxeTable
|
||||||
|
v-if="isActivityComponent"
|
||||||
|
:data="formData?.skus || []"
|
||||||
|
border
|
||||||
|
max-height="500"
|
||||||
|
size="small"
|
||||||
|
class="w-full"
|
||||||
|
>
|
||||||
|
<VxeColumn v-if="isComponent" type="checkbox" width="45" />
|
||||||
|
<VxeColumn align="center" title="图片" min-width="120">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<Image
|
||||||
|
:src="row.picUrl"
|
||||||
|
class="h-[60px] w-[60px] cursor-pointer"
|
||||||
|
:preview="true"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</VxeColumn>
|
||||||
|
<template v-if="formData?.specType">
|
||||||
|
<!-- 根据商品属性动态添加 -->
|
||||||
|
<VxeColumn
|
||||||
|
v-for="(item, index) in tableHeaders"
|
||||||
|
:key="index"
|
||||||
|
:title="item.label"
|
||||||
|
align="center"
|
||||||
|
min-width="80"
|
||||||
|
>
|
||||||
|
<template #default="{ row }">
|
||||||
|
<span class="font-bold text-[#40aaff]">
|
||||||
|
{{ row.properties?.[index]?.valueName }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</VxeColumn>
|
||||||
</template>
|
</template>
|
||||||
</VxeColumn>
|
<VxeColumn align="center" title="商品条码" min-width="100">
|
||||||
<VxeColumn align="center" title="成本价(元)" min-width="80">
|
<template #default="{ row }">
|
||||||
<template #default="{ row }">
|
{{ row.barCode }}
|
||||||
{{ formatToFraction(row.costPrice) }}
|
</template>
|
||||||
</template>
|
</VxeColumn>
|
||||||
</VxeColumn>
|
<VxeColumn align="center" title="销售价(元)" min-width="80">
|
||||||
<VxeColumn align="center" title="库存" min-width="80">
|
<template #default="{ row }">
|
||||||
<template #default="{ row }">
|
{{ formatToFraction(row.price) }}
|
||||||
{{ row.stock }}
|
</template>
|
||||||
</template>
|
</VxeColumn>
|
||||||
</VxeColumn>
|
<VxeColumn align="center" title="市场价(元)" min-width="80">
|
||||||
<!-- 方便扩展每个活动配置的属性不一样 -->
|
<template #default="{ row }">
|
||||||
<slot name="extension"></slot>
|
{{ formatToFraction(row.marketPrice) }}
|
||||||
</VxeTable>
|
</template>
|
||||||
|
</VxeColumn>
|
||||||
|
<VxeColumn align="center" title="成本价(元)" min-width="80">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ formatToFraction(row.costPrice) }}
|
||||||
|
</template>
|
||||||
|
</VxeColumn>
|
||||||
|
<VxeColumn align="center" title="库存" min-width="80">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ row.stock }}
|
||||||
|
</template>
|
||||||
|
</VxeColumn>
|
||||||
|
<!-- 方便扩展每个活动配置的属性不一样 -->
|
||||||
|
<slot name="extension"></slot>
|
||||||
|
</VxeTable>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -6,8 +6,9 @@ import type { MallSpuApi } from '#/api/mall/product/spu';
|
|||||||
import { computed, ref } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
|
|
||||||
import { useVbenModal } from '@vben/common-ui';
|
import { useVbenModal } from '@vben/common-ui';
|
||||||
|
import { fenToYuan } from '@vben/utils';
|
||||||
|
|
||||||
import { message } from 'ant-design-vue';
|
import { Input, message } from 'ant-design-vue';
|
||||||
|
|
||||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
import { getSpu } from '#/api/mall/product/spu';
|
import { getSpu } from '#/api/mall/product/spu';
|
||||||
@@ -23,13 +24,6 @@ const emit = defineEmits<{
|
|||||||
const selectedSkuId = ref<number>();
|
const selectedSkuId = ref<number>();
|
||||||
const spuId = ref<number>();
|
const spuId = ref<number>();
|
||||||
|
|
||||||
// 价格格式化:分转元
|
|
||||||
const fenToYuan = (price?: number | string) => {
|
|
||||||
const numPrice =
|
|
||||||
typeof price === 'string' ? Number.parseFloat(price) : price || 0;
|
|
||||||
return (numPrice / 100).toFixed(2);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 配置列
|
// 配置列
|
||||||
const gridColumns = computed<VxeGridProps['columns']>(() => [
|
const gridColumns = computed<VxeGridProps['columns']>(() => [
|
||||||
{
|
{
|
||||||
@@ -102,11 +96,11 @@ const [Grid, gridApi] = useVbenVxeGrid({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 处理选中
|
// 处理选中
|
||||||
const handleSelected = (row: MallSpuApi.Sku) => {
|
function handleSelected(row: MallSpuApi.Sku) {
|
||||||
emit('change', row);
|
emit('change', row);
|
||||||
modalApi.close();
|
modalApi.close();
|
||||||
selectedSkuId.value = undefined;
|
selectedSkuId.value = undefined;
|
||||||
};
|
}
|
||||||
|
|
||||||
// 初始化弹窗
|
// 初始化弹窗
|
||||||
const [Modal, modalApi] = useVbenModal({
|
const [Modal, modalApi] = useVbenModal({
|
||||||
@@ -133,7 +127,7 @@ const [Modal, modalApi] = useVbenModal({
|
|||||||
<Grid>
|
<Grid>
|
||||||
<!-- 单选列 -->
|
<!-- 单选列 -->
|
||||||
<template #radio-column="{ row }">
|
<template #radio-column="{ row }">
|
||||||
<input
|
<Input
|
||||||
v-model="selectedSkuId"
|
v-model="selectedSkuId"
|
||||||
:value="row.id"
|
:value="row.id"
|
||||||
class="cursor-pointer"
|
class="cursor-pointer"
|
||||||
|
|||||||
Reference in New Issue
Block a user