feat: 商品详情联调2
This commit is contained in:
parent
6b3895b6a1
commit
a31beb08f2
@ -27,14 +27,12 @@
|
|||||||
size="small"
|
size="small"
|
||||||
class="w-40"
|
class="w-40"
|
||||||
@keyup.enter="handleInputConfirm(data)"
|
@keyup.enter="handleInputConfirm(data)"
|
||||||
@blur="handleInputCancel(node, data)"
|
@blur="treeRef.remove(node)"
|
||||||
/>
|
/>
|
||||||
<div>
|
<div>
|
||||||
<el-button type="primary" link @click="onEdit(data)" size="small">编辑 </el-button>
|
<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="primary" link @click="append(data)" size="small"> 添加 </el-button>
|
||||||
<el-button type="danger" size="small" link @click="remove(node, data)">
|
<el-button type="danger" size="small" link @click="onDelete(node)"> 删除 </el-button>
|
||||||
删除
|
|
||||||
</el-button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -86,14 +84,6 @@ const handleInputConfirm = async (data: any) => {
|
|||||||
curId.value = NaN
|
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 append = async (data: Data) => {
|
||||||
const node = treeRef.value.getNode(data.id)
|
const node = treeRef.value.getNode(data.id)
|
||||||
@ -116,16 +106,21 @@ const append = async (data: Data) => {
|
|||||||
treeRef.value.append(newChild, data)
|
treeRef.value.append(newChild, data)
|
||||||
node.expanded = true
|
node.expanded = true
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
inputRef.value.focus()
|
const timer = setTimeout(() => {
|
||||||
|
clearTimeout(timer)
|
||||||
|
inputRef.value.focus()
|
||||||
|
}, 500)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除类目
|
// 删除类目
|
||||||
const remove = (node: Node, data: Data) => {
|
const onDelete = async (node: Node) => {
|
||||||
const parent = node.parent
|
await api.commodity.updateAppCategory.post!({
|
||||||
const children: Tree[] = parent?.data.children || parent?.data
|
id: node.data.id,
|
||||||
const index = children.findIndex((d) => d.id === data.id)
|
isDelete: 1
|
||||||
children.splice(index, 1)
|
})
|
||||||
|
treeRef.value.remove(node)
|
||||||
|
ElMessage.success('删除成功')
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultProps = {
|
const defaultProps = {
|
||||||
|
|||||||
@ -27,83 +27,84 @@
|
|||||||
size="small"
|
size="small"
|
||||||
class="w-40"
|
class="w-40"
|
||||||
@keyup.enter="handleInputConfirm(data)"
|
@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">
|
<template v-if="data.isProperty">
|
||||||
<dl class="flex items-center">
|
<dl class="flex items-center">
|
||||||
<dt class="text-sm text-[#666] mb-2">{{ data.categoryPropertyName }}:</dt>
|
<dt class="text-sm text-[#666] mb-2">{{ data.categoryPropertyName }}:</dt>
|
||||||
<dd class="flex mb-2 flex-wrap">
|
<dd class="flex mb-2 flex-wrap">
|
||||||
<div v-for="child in data.vvPropertyValueList" :key="data.id + '-' + child.id">
|
<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
|
<el-tag
|
||||||
|
v-else
|
||||||
closable
|
closable
|
||||||
effect="plain"
|
effect="plain"
|
||||||
type="primary"
|
type="primary"
|
||||||
class="mr-1"
|
class="mr-1"
|
||||||
|
@click="onClickPropertyValue(child)"
|
||||||
@close="onClosePropertyValue(child.id, data)"
|
@close="onClosePropertyValue(child.id, data)"
|
||||||
>{{ child.categoryPropertyValue }}</el-tag
|
>{{ child.categoryPropertyValue }}</el-tag
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<el-popover
|
<el-input
|
||||||
:visible="visibleProperty[data.id]"
|
ref="propertyValueInputRef"
|
||||||
placement="bottom"
|
class="w-20"
|
||||||
title="请输入属性值"
|
size="small"
|
||||||
:width="200"
|
v-if="visiblePropertyValue[data.id]"
|
||||||
trigger="click"
|
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
|
<el-button
|
||||||
type="danger"
|
type="danger"
|
||||||
size="small"
|
size="small"
|
||||||
class="ml-2 !text-white"
|
class="!text-[10px] !px-2 !py-1 !pb-0.5"
|
||||||
@click="onDeleteProperty(data.id)"
|
@click="onDeleteProperty(node, data.id)"
|
||||||
>删除属性</el-button
|
>删除属性</el-button
|
||||||
>
|
>
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</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="onEdit(data)" size="small">编辑 </el-button>
|
||||||
<el-button type="primary" link @click="append(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 type="danger" size="small" link @click="onDelete(node)"> 删除 </el-button>
|
||||||
删除
|
|
||||||
</el-button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -156,12 +157,14 @@ const handleInputConfirm = async (data: any) => {
|
|||||||
curId.value = NaN
|
curId.value = NaN
|
||||||
}
|
}
|
||||||
|
|
||||||
// 失焦
|
// 删除类目
|
||||||
const handleInputCancel = (node: Node, data: Data) => {
|
const onDelete = async (node: Node) => {
|
||||||
if (data.id === Infinity) {
|
await api.commodity.updateCategory.post!({
|
||||||
remove(node, data)
|
id: node.data.id,
|
||||||
}
|
isDelete: 1
|
||||||
curId.value = NaN
|
})
|
||||||
|
treeRef.value.remove(node)
|
||||||
|
ElMessage.success('删除成功')
|
||||||
}
|
}
|
||||||
|
|
||||||
// 增加类目
|
// 增加类目
|
||||||
@ -170,7 +173,7 @@ const append = async (data: Data) => {
|
|||||||
curId.value = Infinity
|
curId.value = Infinity
|
||||||
curParentId.value = data.id
|
curParentId.value = data.id
|
||||||
const newChild = { id: curId.value, name: '', label2: 'test', hasChild: false }
|
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) => {
|
await api.commodity.getCategoryList.post!<any>({ parentId: data.id || 0 }).then((res) => {
|
||||||
res.data.forEach((item: any) => {
|
res.data.forEach((item: any) => {
|
||||||
treeRef.value.append(
|
treeRef.value.append(
|
||||||
@ -186,18 +189,13 @@ const append = async (data: Data) => {
|
|||||||
treeRef.value.append(newChild, data)
|
treeRef.value.append(newChild, data)
|
||||||
node.expanded = true
|
node.expanded = true
|
||||||
nextTick(() => {
|
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 = {
|
const defaultProps = {
|
||||||
label: 'name',
|
label: 'name',
|
||||||
children: 'children',
|
children: 'children',
|
||||||
@ -222,6 +220,8 @@ const handleLoadNode = (node, resolve) => {
|
|||||||
resolve(
|
resolve(
|
||||||
res.data.map((item: any) => ({
|
res.data.map((item: any) => ({
|
||||||
...item,
|
...item,
|
||||||
|
vvCategoryPropertyDTOList: item.vvCategoryPropertyDTOList || [],
|
||||||
|
hasOriginChild: item.hasChild,
|
||||||
hasChild: item.hasChild || !!item.vvCategoryPropertyDTOList?.length,
|
hasChild: item.hasChild || !!item.vvCategoryPropertyDTOList?.length,
|
||||||
children: item.hasChild ? [] : undefined
|
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 inputPropertyValue = ref('')
|
||||||
const visiblePropertyType = ref<Record<number, boolean>>({})
|
const visiblePropertyType = ref<Record<number, boolean>>({})
|
||||||
const inputPropertyTypeValue = ref('')
|
const inputPropertyTypeValue = ref('')
|
||||||
|
|
||||||
// 删除类目的属性
|
// 删除类目的属性值
|
||||||
const onClosePropertyValue = async (id: number, data: any) => {
|
const onClosePropertyValue = async (id: number, data: any) => {
|
||||||
const i = data.vvPropertyValueList.findIndex((item: any) => item.id === id)
|
const i = data.vvPropertyValueList.findIndex((item: any) => item.id === id)
|
||||||
await api.commodity.deleteCategoryPropertyValue.post!({ id })
|
await api.commodity.deleteCategoryPropertyValue.post!({ id })
|
||||||
@ -250,27 +250,40 @@ const onAddPropertyValue = async (data: any = {}) => {
|
|||||||
categoryPropertyId: data.id,
|
categoryPropertyId: data.id,
|
||||||
categoryPropertyValue: inputPropertyValue.value
|
categoryPropertyValue: inputPropertyValue.value
|
||||||
})
|
})
|
||||||
// testzc 将新增的数据返回到页面中
|
|
||||||
data.vvPropertyValueList.push(res.data)
|
data.vvPropertyValueList.push(res.data)
|
||||||
}
|
}
|
||||||
visibleProperty.value[data.id] = false
|
visiblePropertyValue.value[data.id] = false
|
||||||
inputPropertyValue.value = ''
|
inputPropertyValue.value = ''
|
||||||
ElMessage.success('新增成功')
|
ElMessage.success('新增成功')
|
||||||
}
|
}
|
||||||
|
|
||||||
// 新增属性类型
|
// 新增属性类型
|
||||||
const onAddPropertyType = async (data: any = {}) => {
|
const onAddPropertyType = async (data: any = {}) => {
|
||||||
console.warn('----- my data is data111: ', data)
|
const node = treeRef.value.getNode(data.id)
|
||||||
if (inputPropertyTypeValue.value) {
|
if (inputPropertyTypeValue.value) {
|
||||||
const res = await api.commodity.updateCategoryProperty.post!({
|
const res = await api.commodity.updateCategoryProperty.post!<{
|
||||||
categoryId: data.categoryId,
|
id: number
|
||||||
categoryName: data.categoryName,
|
categoryPropertyName: string
|
||||||
|
}>({
|
||||||
|
categoryId: data.id,
|
||||||
|
categoryName: data.name,
|
||||||
categoryPropertyName: inputPropertyTypeValue.value
|
categoryPropertyName: inputPropertyTypeValue.value
|
||||||
})
|
})
|
||||||
console.warn('----- my data is data.id: ', data.id)
|
const newData = {
|
||||||
res.data.vvPropertyValueList = []
|
...res.data,
|
||||||
const newData = res.data
|
hasChild: 0,
|
||||||
// testzc把新的数据塞到树里去
|
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
|
visiblePropertyType.value[data.id] = false
|
||||||
inputPropertyTypeValue.value = ''
|
inputPropertyTypeValue.value = ''
|
||||||
ElMessage.success('新增成功')
|
ElMessage.success('新增成功')
|
||||||
@ -278,15 +291,54 @@ const onAddPropertyType = async (data: any = {}) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 删除属性
|
// 删除属性
|
||||||
const onDeleteProperty = async (id: number) => {
|
const onDeleteProperty = async (node: Node, id: number) => {
|
||||||
handleMessageBox({
|
handleMessageBox({
|
||||||
msg: `是否删除属性?`,
|
msg: `是否删除属性?`,
|
||||||
success: api.commodity.deleteCategoryProperty.post!,
|
success: api.commodity.deleteCategoryProperty.post!,
|
||||||
data: { id }
|
data: { id }
|
||||||
}).then(() => {
|
}).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>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@ -5,7 +5,7 @@ export const initConfig = () => {
|
|||||||
dialog: [
|
dialog: [
|
||||||
{
|
{
|
||||||
title: { label: '商品标题', class: '!w-full', rule: true },
|
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' },
|
mainImageUrl: { label: '主图', slot: 'mainFile' },
|
||||||
videoUrl: { label: '视频', slot: 'videoFile' },
|
videoUrl: { label: '视频', slot: 'videoFile' },
|
||||||
subImageUrl: { label: '副图', slot: 'subFile' },
|
subImageUrl: { label: '副图', slot: 'subFile' },
|
||||||
|
|||||||
@ -22,6 +22,8 @@ export const handleGetDialogData = (
|
|||||||
defaultCheckedNodes.value.app = [data.appCategoryId1, data.appCategoryId2]
|
defaultCheckedNodes.value.app = [data.appCategoryId1, data.appCategoryId2]
|
||||||
result.isTest = data.isTest
|
result.isTest = data.isTest
|
||||||
result.title = data.title
|
result.title = data.title
|
||||||
|
result.feature1 = data.feature1
|
||||||
|
result.feature2 = data.feature2
|
||||||
const files = [
|
const files = [
|
||||||
{
|
{
|
||||||
fileName: '主图',
|
fileName: '主图',
|
||||||
|
|||||||
@ -79,6 +79,22 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="测试商品">
|
<el-form-item label="测试商品">
|
||||||
<el-switch v-model="$dialog.data.isTest" active-value="1" inactive-value="0" />
|
<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
|
<el-popover
|
||||||
:visible="visiblePropertyLine"
|
:visible="visiblePropertyLine"
|
||||||
placement="bottom"
|
placement="bottom"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user