feat:【mall 商城】商品发布 - 库存价格【antd】100%: 迁移完成

This commit is contained in:
puhui999
2025-10-21 16:39:54 +08:00
parent 93149876e5
commit 6bbf878171
3 changed files with 36 additions and 25 deletions

View File

@@ -29,7 +29,7 @@ interface Props {
isDetail?: boolean;
}
const inputValue = ref(''); // 输入框值
const inputValue = ref<string[]>([]); // 输入框值tags 模式使用数组)
const attributeIndex = ref<null | number>(null); // 获取焦点时记录当前属性项的index
// 输入框显隐控制
const inputVisible = computed(() => (index: number) => {
@@ -95,26 +95,29 @@ const showInput = async (index: number) => {
// 定义 success 事件,用于操作成功后的回调
const handleInputConfirm = async (index: number, propertyId: number) => {
if (inputValue.value) {
// 从数组中取最后一个输入的值tags 模式下 inputValue 是数组)
const currentValue = inputValue.value?.[inputValue.value.length - 1]?.trim();
if (currentValue) {
// 1. 重复添加校验
if (
attributeList.value?.[index]?.values?.find(
(item) => item.name === inputValue.value,
(item) => item.name === currentValue,
)
) {
message.warning('已存在相同属性值,请重试');
attributeIndex.value = null;
inputValue.value = '';
inputValue.value = [];
return;
}
// 2.1 情况一:属性值已存在,则直接使用并结束
const existValue = attributeOptions.value.find(
(item) => item.name === inputValue.value,
(item) => item.name === currentValue,
);
if (existValue) {
attributeIndex.value = null;
inputValue.value = '';
inputValue.value = [];
attributeList.value?.[index]?.values?.push({
id: existValue.id!,
name: existValue.name,
@@ -127,11 +130,11 @@ const handleInputConfirm = async (index: number, propertyId: number) => {
try {
const id = await createPropertyValue({
propertyId,
name: inputValue.value,
name: currentValue,
});
attributeList.value?.[index]?.values?.push({
id,
name: inputValue.value,
name: currentValue,
});
message.success($t('common.createSuccess'));
emit('success', attributeList.value);
@@ -140,7 +143,7 @@ const handleInputConfirm = async (index: number, propertyId: number) => {
}
}
attributeIndex.value = null;
inputValue.value = '';
inputValue.value = [];
};
/** 获取商品属性下拉选项 */
@@ -179,11 +182,11 @@ const getAttributeOptions = async (propertyId: number) => {
:ref="setInputRef"
v-model:value="inputValue"
allow-clear
class="!w-30"
mode="tags"
:max-tag-count="1"
:filter-option="true"
size="small"
style="width: 100px"
@blur="handleInputConfirm(index, item.id)"
@change="handleInputConfirm(index, item.id)"
@keyup.enter="handleInputConfirm(index, item.id)"

View File

@@ -7,7 +7,7 @@ import type { MallSpuApi } from '#/api/mall/product/spu';
import { ref, watch } from 'vue';
import { formatToFraction, isEmpty } from '@vben/utils';
import { copyValueToTarget, formatToFraction, isEmpty } from '@vben/utils';
import { Button, Image, Input, InputNumber, message } from 'ant-design-vue';
@@ -59,20 +59,11 @@ const skuList = ref<MallSpuApi.Sku[]>([
},
]); // 批量添加时的临时数据
/** 商品图预览 */
const imagePreview = (imgUrl: string) => {
// TODO @puhui999: 图片预览
// createImageViewer({
// zIndex: 9_999_999,
// urlList: [imgUrl],
// });
};
/** 批量添加 */
const batchAdd = () => {
validateProperty();
formData.value!.skus!.forEach((item: MallSpuApi.Sku) => {
// copyValueToTarget(item, skuList.value[0]);
copyValueToTarget(item, skuList.value[0]);
});
};
@@ -478,8 +469,7 @@ defineExpose({ generateTableData, validateSku, getSkuTableRef });
v-if="row.picUrl"
:src="row.picUrl"
class="h-[50px] w-[50px] cursor-pointer"
:preview="false"
@click="imagePreview(row.picUrl)"
:preview="true"
/>
</template>
</VxeColumn>
@@ -563,8 +553,7 @@ defineExpose({ generateTableData, validateSku, getSkuTableRef });
<Image
:src="row.picUrl"
class="h-[60px] w-[60px] cursor-pointer"
:preview="false"
@click="imagePreview(row.picUrl)"
:preview="true"
/>
</template>
</VxeColumn>

View File

@@ -68,3 +68,22 @@ export const getUrlValue = (
const url = new URL(decodeURIComponent(urlStr));
return url.searchParams.get(key) ?? '';
};
/**
* 将值复制到目标对象且以目标对象属性为准target: {a:1} source:{a:2,b:3} 结果为:{a:2}
* @param target 目标对象
* @param source 源对象
*/
export const copyValueToTarget = (target: any, source: any) => {
const newObj = Object.assign({}, target, source);
// 删除多余属性
Object.keys(newObj).forEach((key) => {
// 如果不是target中的属性则删除
if (!Object.keys(target).includes(key)) {
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
delete newObj[key];
}
});
// 更新目标对象值
Object.assign(target, newObj);
};