feat: 商品详情联调2

This commit is contained in:
zc 2025-10-28 23:21:44 +08:00
parent 6b3895b6a1
commit a31beb08f2
5 changed files with 164 additions and 99 deletions

View File

@ -27,14 +27,12 @@
size="small"
class="w-40"
@keyup.enter="handleInputConfirm(data)"
@blur="handleInputCancel(node, data)"
@blur="treeRef.remove(node)"
/>
<div>
<el-button type="primary" link @click="onEdit(data)" size="small">编辑 </el-button>
<el-button type="primary" link @click="append(data)" size="small"> 添加 </el-button>
<el-button type="danger" size="small" link @click="remove(node, data)">
删除
</el-button>
<el-button type="danger" size="small" link @click="onDelete(node)"> 删除 </el-button>
</div>
</div>
</template>
@ -86,14 +84,6 @@ const handleInputConfirm = async (data: any) => {
curId.value = NaN
}
//
const handleInputCancel = (node: Node, data: Data) => {
if (data.id === Infinity) {
remove(node, data)
}
curId.value = NaN
}
//
const append = async (data: Data) => {
const node = treeRef.value.getNode(data.id)
@ -116,16 +106,21 @@ const append = async (data: Data) => {
treeRef.value.append(newChild, data)
node.expanded = true
nextTick(() => {
inputRef.value.focus()
const timer = setTimeout(() => {
clearTimeout(timer)
inputRef.value.focus()
}, 500)
})
}
//
const remove = (node: Node, data: Data) => {
const parent = node.parent
const children: Tree[] = parent?.data.children || parent?.data
const index = children.findIndex((d) => d.id === data.id)
children.splice(index, 1)
const onDelete = async (node: Node) => {
await api.commodity.updateAppCategory.post!({
id: node.data.id,
isDelete: 1
})
treeRef.value.remove(node)
ElMessage.success('删除成功')
}
const defaultProps = {

View File

@ -27,83 +27,84 @@
size="small"
class="w-40"
@keyup.enter="handleInputConfirm(data)"
@blur="handleInputCancel(node, data)"
@blur="treeRef.remove(node)"
/>
<template v-if="!data.hasOriginChild && !data.isProperty">
<el-input
ref="propertyTypeInputRef"
class="w-20"
size="small"
v-if="visiblePropertyType[data.id]"
v-model="inputPropertyTypeValue"
@keyup.enter="onAddPropertyType(data)"
@blur="visiblePropertyType[data.id] = false"
></el-input>
<el-button
v-else
type="primary"
size="small"
class="ml-2 !text-[10px] !px-2 !py-1 !pb-0.5 -mt-0.5"
@click="onClickPropertyTypeBtn(data)"
>新增属性</el-button
>
</template>
<template v-if="data.isProperty">
<dl class="flex items-center">
<dt class="text-sm text-[#666] mb-2">{{ data.categoryPropertyName }}</dt>
<dd class="flex mb-2 flex-wrap">
<div v-for="child in data.vvPropertyValueList" :key="data.id + '-' + child.id">
<el-input
v-if="curPropertyValueId === child.id"
ref="editPropertyValueInputRef"
class="w-20"
size="small"
v-model="inputEditPropertyValue"
@keyup.enter="onEditPropertyValue(child)"
@blur="curPropertyValueId = NaN"
></el-input>
<el-tag
v-else
closable
effect="plain"
type="primary"
class="mr-1"
@click="onClickPropertyValue(child)"
@close="onClosePropertyValue(child.id, data)"
>{{ child.categoryPropertyValue }}</el-tag
>
</div>
<el-popover
:visible="visibleProperty[data.id]"
placement="bottom"
title="请输入属性值"
:width="200"
trigger="click"
<el-input
ref="propertyValueInputRef"
class="w-20"
size="small"
v-if="visiblePropertyValue[data.id]"
v-model="inputPropertyValue"
@keyup.enter="onAddPropertyValue(data)"
@blur="visiblePropertyValue[data.id] = false"
></el-input>
<el-button
v-else
type="primary"
size="small"
class="ml-2 !text-[10px] !px-2 !py-1 !pb-0.5"
@click="onClickPropertyBtn(data)"
>新增属性值</el-button
>
<template #reference>
<el-button
type="primary"
size="small"
class="ml-2 !text-white"
@click="visibleProperty[data.id] = true"
>新增属性值</el-button
>
</template>
<el-input
v-model="inputPropertyValue"
@keyup.enter="onAddPropertyValue(data)"
@blur="visibleProperty[data.id] = false"
></el-input>
</el-popover>
<el-popover
:visible="visiblePropertyType[data.id]"
placement="bottom"
title="请输入属性标题"
:width="200"
trigger="click"
>
<template #reference>
<el-button
type="primary"
size="small"
class="ml-2 !text-white"
@click="visiblePropertyType[data.id] = true"
>新增属性</el-button
>
</template>
<el-input
v-model="inputPropertyTypeValue"
@keyup.enter="onAddPropertyType(data)"
@blur="visiblePropertyType[data.id] = false"
></el-input>
</el-popover>
<el-button
type="danger"
size="small"
class="ml-2 !text-white"
@click="onDeleteProperty(data.id)"
class="!text-[10px] !px-2 !py-1 !pb-0.5"
@click="onDeleteProperty(node, data.id)"
>删除属性</el-button
>
</dd>
</dl>
</template>
</div>
<div>
<div v-if="!data.isProperty">
<el-button type="primary" link @click="onEdit(data)" size="small">编辑 </el-button>
<el-button type="primary" link @click="append(data)" size="small"> 添加 </el-button>
<el-button type="danger" size="small" link @click="remove(node, data)">
删除
</el-button>
<el-button type="danger" size="small" link @click="onDelete(node)"> 删除 </el-button>
</div>
</div>
</template>
@ -156,12 +157,14 @@ const handleInputConfirm = async (data: any) => {
curId.value = NaN
}
//
const handleInputCancel = (node: Node, data: Data) => {
if (data.id === Infinity) {
remove(node, data)
}
curId.value = NaN
//
const onDelete = async (node: Node) => {
await api.commodity.updateCategory.post!({
id: node.data.id,
isDelete: 1
})
treeRef.value.remove(node)
ElMessage.success('删除成功')
}
//
@ -170,7 +173,7 @@ const append = async (data: Data) => {
curId.value = Infinity
curParentId.value = data.id
const newChild = { id: curId.value, name: '', label2: 'test', hasChild: false }
if (!node.expanded) {
if (!node.childNodes.length) {
await api.commodity.getCategoryList.post!<any>({ parentId: data.id || 0 }).then((res) => {
res.data.forEach((item: any) => {
treeRef.value.append(
@ -186,18 +189,13 @@ const append = async (data: Data) => {
treeRef.value.append(newChild, data)
node.expanded = true
nextTick(() => {
inputRef.value.focus()
const timer = setTimeout(() => {
clearTimeout(timer)
inputRef.value.focus()
}, 500)
})
}
//
const remove = (node: Node, data: Data) => {
const parent = node.parent
const children: Tree[] = parent?.data.children || parent?.data
const index = children.findIndex((d) => d.id === data.id)
children.splice(index, 1)
}
const defaultProps = {
label: 'name',
children: 'children',
@ -222,6 +220,8 @@ const handleLoadNode = (node, resolve) => {
resolve(
res.data.map((item: any) => ({
...item,
vvCategoryPropertyDTOList: item.vvCategoryPropertyDTOList || [],
hasOriginChild: item.hasChild,
hasChild: item.hasChild || !!item.vvCategoryPropertyDTOList?.length,
children: item.hasChild ? [] : undefined
}))
@ -230,12 +230,12 @@ const handleLoadNode = (node, resolve) => {
}
}
const visibleProperty = ref<Record<number, boolean>>({})
const visiblePropertyValue = ref<Record<number, boolean>>({})
const inputPropertyValue = ref('')
const visiblePropertyType = ref<Record<number, boolean>>({})
const inputPropertyTypeValue = ref('')
//
//
const onClosePropertyValue = async (id: number, data: any) => {
const i = data.vvPropertyValueList.findIndex((item: any) => item.id === id)
await api.commodity.deleteCategoryPropertyValue.post!({ id })
@ -250,27 +250,40 @@ const onAddPropertyValue = async (data: any = {}) => {
categoryPropertyId: data.id,
categoryPropertyValue: inputPropertyValue.value
})
// testzc
data.vvPropertyValueList.push(res.data)
}
visibleProperty.value[data.id] = false
visiblePropertyValue.value[data.id] = false
inputPropertyValue.value = ''
ElMessage.success('新增成功')
}
//
const onAddPropertyType = async (data: any = {}) => {
console.warn('----- my data is data111: ', data)
const node = treeRef.value.getNode(data.id)
if (inputPropertyTypeValue.value) {
const res = await api.commodity.updateCategoryProperty.post!({
categoryId: data.categoryId,
categoryName: data.categoryName,
const res = await api.commodity.updateCategoryProperty.post!<{
id: number
categoryPropertyName: string
}>({
categoryId: data.id,
categoryName: data.name,
categoryPropertyName: inputPropertyTypeValue.value
})
console.warn('----- my data is data.id: ', data.id)
res.data.vvPropertyValueList = []
const newData = res.data
// testzc
const newData = {
...res.data,
hasChild: 0,
isProperty: 1,
vvPropertyValueList: []
}
data.vvCategoryPropertyDTOList.push(newData)
if (!node.childNodes.length) {
data.vvCategoryPropertyDTOList.forEach((item: any) => {
treeRef.value.append({ ...item, hasChild: 0, isProperty: 1 }, data)
})
} else {
treeRef.value.append(newData, data)
}
node.expanded = true
visiblePropertyType.value[data.id] = false
inputPropertyTypeValue.value = ''
ElMessage.success('新增成功')
@ -278,15 +291,54 @@ const onAddPropertyType = async (data: any = {}) => {
}
//
const onDeleteProperty = async (id: number) => {
const onDeleteProperty = async (node: Node, id: number) => {
handleMessageBox({
msg: `是否删除属性?`,
success: api.commodity.deleteCategoryProperty.post!,
data: { id }
}).then(() => {
// testzc
treeRef.value.remove(node)
})
}
const propertyTypeInputRef = ref()
const onClickPropertyTypeBtn = (data: any) => {
visiblePropertyType.value[data.id] = true
nextTick(() => {
propertyTypeInputRef.value.input!.focus()
})
}
const propertyValueInputRef = ref()
const onClickPropertyBtn = (data: any) => {
visiblePropertyValue.value[data.id] = true
nextTick(() => {
propertyValueInputRef.value.input!.focus()
})
}
const curPropertyValueId = ref(NaN)
const inputEditPropertyValue = ref('')
const editPropertyValueInputRef = ref()
const onClickPropertyValue = (data: any) => {
curPropertyValueId.value = data.id
inputEditPropertyValue.value = data.categoryPropertyValue
nextTick(() => {
const timer = setTimeout(() => {
clearTimeout(timer)
editPropertyValueInputRef.value[0].input!.focus()
}, 500)
})
}
const onEditPropertyValue = async (data: any) => {
await api.commodity.updateCategoryPropertyValue.post!({
id: data.id,
categoryPropertyValue: inputEditPropertyValue.value
})
ElMessage.success('编辑成功')
data.categoryPropertyValue = inputEditPropertyValue.value
curPropertyValueId.value = NaN
inputEditPropertyValue.value = ''
}
</script>
<style lang="scss" scoped>

View File

@ -5,7 +5,7 @@ export const initConfig = () => {
dialog: [
{
title: { label: '商品标题', class: '!w-full', rule: true },
appCategoryIds: { label: 'app类目', slot: 'appCategoryId', rule: true },
appCategoryId: { label: 'app类目', slot: 'appCategoryId', rule: true },
mainImageUrl: { label: '主图', slot: 'mainFile' },
videoUrl: { label: '视频', slot: 'videoFile' },
subImageUrl: { label: '副图', slot: 'subFile' },

View File

@ -22,6 +22,8 @@ export const handleGetDialogData = (
defaultCheckedNodes.value.app = [data.appCategoryId1, data.appCategoryId2]
result.isTest = data.isTest
result.title = data.title
result.feature1 = data.feature1
result.feature2 = data.feature2
const files = [
{
fileName: '主图',

View File

@ -79,6 +79,22 @@
</el-form-item>
<el-form-item label="测试商品">
<el-switch v-model="$dialog.data.isTest" active-value="1" inactive-value="0" />
</el-form-item>
<el-form-item label="特色">
<div class="flex">
<el-input
class="w-1/2"
v-model="$dialog.data.feature1"
placeholder="请输入特色1"
></el-input>
<el-input
class="w-1/2 ml-2"
v-model="$dialog.data.feature2"
placeholder="请输入特色2"
></el-input>
</div>
</el-form-item>
<el-form-item>
<el-popover
:visible="visiblePropertyLine"
placement="bottom"