feat:【mall】diy editor 的 hot-zone 代码优化(100%)完成商品分类的支持
This commit is contained in:
@@ -3,32 +3,33 @@ import { computed, onMounted, ref } from 'vue';
|
|||||||
|
|
||||||
import { handleTree } from '@vben/utils';
|
import { handleTree } from '@vben/utils';
|
||||||
|
|
||||||
|
import { ElTreeSelect } from 'element-plus';
|
||||||
|
|
||||||
import { getCategoryList } from '#/api/mall/product/category';
|
import { getCategoryList } from '#/api/mall/product/category';
|
||||||
|
|
||||||
/** 商品分类选择组件 */
|
/** 商品分类选择组件 */
|
||||||
defineOptions({ name: 'ProductCategorySelect' });
|
defineOptions({ name: 'ProductCategorySelect' });
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
// 选中的ID
|
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: [Number, Array<Number>],
|
type: [Number, Array<Number>],
|
||||||
default: undefined,
|
default: undefined,
|
||||||
},
|
}, // 选中的 ID
|
||||||
// 是否多选
|
|
||||||
multiple: {
|
multiple: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
}, // 是否多选
|
||||||
// 上级品类的编号
|
|
||||||
parentId: {
|
parentId: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: undefined,
|
default: undefined,
|
||||||
},
|
}, // 上级品类的编号
|
||||||
});
|
});
|
||||||
|
|
||||||
/** 分类选择 */
|
/** 分类选择 */
|
||||||
const emit = defineEmits(['update:modelValue']);
|
const emit = defineEmits(['update:modelValue']);
|
||||||
|
|
||||||
|
const categoryList = ref<any[]>([]); // 分类树
|
||||||
|
|
||||||
/** 选中的分类 ID */
|
/** 选中的分类 ID */
|
||||||
const selectCategoryId = computed({
|
const selectCategoryId = computed({
|
||||||
get: () => {
|
get: () => {
|
||||||
@@ -40,7 +41,6 @@ const selectCategoryId = computed({
|
|||||||
});
|
});
|
||||||
|
|
||||||
/** 初始化 */
|
/** 初始化 */
|
||||||
const categoryList = ref<any[]>([]); // 分类树
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
const data = await getCategoryList({
|
const data = await getCategoryList({
|
||||||
parentId: props.parentId,
|
parentId: props.parentId,
|
||||||
@@ -49,20 +49,19 @@ onMounted(async () => {
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<el-tree-select
|
<ElTreeSelect
|
||||||
v-model="selectCategoryId"
|
v-model="selectCategoryId"
|
||||||
:data="categoryList"
|
:data="categoryList"
|
||||||
|
node-key="id"
|
||||||
:props="{
|
:props="{
|
||||||
children: 'children',
|
children: 'children',
|
||||||
label: 'name',
|
label: 'name',
|
||||||
value: 'id',
|
|
||||||
isLeaf: 'leaf',
|
|
||||||
emitPath: false,
|
|
||||||
}"
|
}"
|
||||||
:multiple="multiple"
|
:multiple="multiple"
|
||||||
:show-checkbox="multiple"
|
:show-checkbox="multiple"
|
||||||
class="w-1/1"
|
check-strictly
|
||||||
node-key="id"
|
default-expand-all
|
||||||
|
class="w-full"
|
||||||
placeholder="请选择商品分类"
|
placeholder="请选择商品分类"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export { default as ProductCategorySelect } from './category-select.vue';
|
||||||
@@ -8,9 +8,15 @@ import { nextTick, ref } from 'vue';
|
|||||||
import { useVbenModal } from '@vben/common-ui';
|
import { useVbenModal } from '@vben/common-ui';
|
||||||
import { getUrlNumberValue } from '@vben/utils';
|
import { getUrlNumberValue } from '@vben/utils';
|
||||||
|
|
||||||
import { ElButton, ElScrollbar, ElTooltip } from 'element-plus';
|
import {
|
||||||
|
ElButton,
|
||||||
|
ElForm,
|
||||||
|
ElFormItem,
|
||||||
|
ElScrollbar,
|
||||||
|
ElTooltip,
|
||||||
|
} from 'element-plus';
|
||||||
|
|
||||||
import ProductCategorySelect from '#/views/mall/product/category/components/product-category-select.vue';
|
import { ProductCategorySelect } from '#/views/mall/product/category/components/';
|
||||||
|
|
||||||
import { APP_LINK_GROUP_LIST, APP_LINK_TYPE_ENUM } from './data';
|
import { APP_LINK_GROUP_LIST, APP_LINK_TYPE_ENUM } from './data';
|
||||||
|
|
||||||
@@ -33,9 +39,7 @@ const groupBtnRefs = ref<ButtonInstance[]>([]); // 分组引用列表
|
|||||||
const detailSelectDialog = ref<{
|
const detailSelectDialog = ref<{
|
||||||
id?: number;
|
id?: number;
|
||||||
type?: APP_LINK_TYPE_ENUM;
|
type?: APP_LINK_TYPE_ENUM;
|
||||||
visible: boolean;
|
|
||||||
}>({
|
}>({
|
||||||
visible: false,
|
|
||||||
id: undefined,
|
id: undefined,
|
||||||
type: undefined,
|
type: undefined,
|
||||||
}); // 详情选择对话框
|
}); // 详情选择对话框
|
||||||
@@ -48,6 +52,14 @@ const [Modal, modalApi] = useVbenModal({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const [DetailSelectModal, detailSelectModalApi] = useVbenModal({
|
||||||
|
onConfirm() {
|
||||||
|
detailSelectModalApi.close();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
defineExpose({ open });
|
||||||
|
|
||||||
/** 打开弹窗 */
|
/** 打开弹窗 */
|
||||||
async function open(link: string) {
|
async function open(link: string) {
|
||||||
activeAppLink.value.path = link;
|
activeAppLink.value.path = link;
|
||||||
@@ -69,8 +81,6 @@ async function open(link: string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({ open });
|
|
||||||
|
|
||||||
/** 处理 APP 链接选中 */
|
/** 处理 APP 链接选中 */
|
||||||
function handleAppLinkSelected(appLink: AppLink) {
|
function handleAppLinkSelected(appLink: AppLink) {
|
||||||
if (!isSameLink(appLink.path, activeAppLink.value.path)) {
|
if (!isSameLink(appLink.path, activeAppLink.value.path)) {
|
||||||
@@ -78,7 +88,6 @@ function handleAppLinkSelected(appLink: AppLink) {
|
|||||||
}
|
}
|
||||||
switch (appLink.type) {
|
switch (appLink.type) {
|
||||||
case APP_LINK_TYPE_ENUM.PRODUCT_CATEGORY_LIST: {
|
case APP_LINK_TYPE_ENUM.PRODUCT_CATEGORY_LIST: {
|
||||||
detailSelectDialog.value.visible = true;
|
|
||||||
detailSelectDialog.value.type = appLink.type;
|
detailSelectDialog.value.type = appLink.type;
|
||||||
// 返显
|
// 返显
|
||||||
detailSelectDialog.value.id =
|
detailSelectDialog.value.id =
|
||||||
@@ -86,6 +95,7 @@ function handleAppLinkSelected(appLink: AppLink) {
|
|||||||
'id',
|
'id',
|
||||||
`http://127.0.0.1${activeAppLink.value.path}`,
|
`http://127.0.0.1${activeAppLink.value.path}`,
|
||||||
) || undefined;
|
) || undefined;
|
||||||
|
detailSelectModalApi.open();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
@@ -144,41 +154,41 @@ function isSameLink(link1: string, link2: string) {
|
|||||||
|
|
||||||
/** 处理详情选择 */
|
/** 处理详情选择 */
|
||||||
function handleProductCategorySelected(id: number) {
|
function handleProductCategorySelected(id: number) {
|
||||||
// TODO @AI:这里有点问题;activeAppLink 地址;
|
// 生成 activeAppLink
|
||||||
const url = new URL(activeAppLink.value.path, 'http://127.0.0.1');
|
const url = new URL(activeAppLink.value.path, 'http://127.0.0.1');
|
||||||
// 修改 id 参数
|
|
||||||
url.searchParams.set('id', `${id}`);
|
url.searchParams.set('id', `${id}`);
|
||||||
// 排除域名
|
|
||||||
activeAppLink.value.path = `${url.pathname}${url.search}`;
|
activeAppLink.value.path = `${url.pathname}${url.search}`;
|
||||||
// 关闭对话框
|
|
||||||
detailSelectDialog.value.visible = false;
|
// 关闭对话框,并重置 id
|
||||||
// 重置 id
|
detailSelectModalApi.close();
|
||||||
detailSelectDialog.value.id = undefined;
|
detailSelectDialog.value.id = undefined;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<Modal title="选择链接" class="w-[65%]">
|
<Modal title="选择链接" class="w-[65%]">
|
||||||
<div class="flex h-[500px] gap-2">
|
<div class="flex h-[500px] gap-2">
|
||||||
<!-- 左侧分组列表 -->
|
<div class="flex flex-col">
|
||||||
<ElScrollbar
|
<!-- 左侧分组列表 -->
|
||||||
wrap-class="h-full"
|
<ElScrollbar
|
||||||
ref="groupScrollbar"
|
wrap-class="h-full"
|
||||||
view-class="flex flex-col"
|
ref="groupScrollbar"
|
||||||
class="border-r border-gray-200 pr-2"
|
view-class="flex flex-col"
|
||||||
>
|
class="border-r border-gray-200 pr-2"
|
||||||
<ElButton
|
|
||||||
v-for="(group, groupIndex) in APP_LINK_GROUP_LIST"
|
|
||||||
:key="groupIndex"
|
|
||||||
class="ml-0 mr-4 w-[90px] justify-start"
|
|
||||||
:class="[{ active: activeGroup === group.name }]"
|
|
||||||
ref="groupBtnRefs"
|
|
||||||
:text="activeGroup !== group.name"
|
|
||||||
:type="activeGroup === group.name ? 'primary' : 'default'"
|
|
||||||
@click="handleGroupSelected(group.name)"
|
|
||||||
>
|
>
|
||||||
{{ group.name }}
|
<ElButton
|
||||||
</ElButton>
|
v-for="(group, groupIndex) in APP_LINK_GROUP_LIST"
|
||||||
</ElScrollbar>
|
:key="groupIndex"
|
||||||
|
class="!ml-0 mb-1 mr-4 !justify-start"
|
||||||
|
:class="[{ active: activeGroup === group.name }]"
|
||||||
|
ref="groupBtnRefs"
|
||||||
|
:text="activeGroup !== group.name"
|
||||||
|
:type="activeGroup === group.name ? 'primary' : 'default'"
|
||||||
|
@click="handleGroupSelected(group.name)"
|
||||||
|
>
|
||||||
|
{{ group.name }}
|
||||||
|
</ElButton>
|
||||||
|
</ElScrollbar>
|
||||||
|
</div>
|
||||||
<!-- 右侧链接列表 -->
|
<!-- 右侧链接列表 -->
|
||||||
<ElScrollbar
|
<ElScrollbar
|
||||||
class="h-full flex-1 pl-2"
|
class="h-full flex-1 pl-2"
|
||||||
@@ -219,9 +229,9 @@ function handleProductCategorySelected(id: number) {
|
|||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
<el-dialog v-model="detailSelectDialog.visible" title="" width="50%">
|
<DetailSelectModal title="选择分类" class="w-[65%]">
|
||||||
<el-form class="min-h-[200px]">
|
<ElForm class="min-h-[200px]">
|
||||||
<el-form-item
|
<ElFormItem
|
||||||
label="选择分类"
|
label="选择分类"
|
||||||
v-if="
|
v-if="
|
||||||
detailSelectDialog.type === APP_LINK_TYPE_ENUM.PRODUCT_CATEGORY_LIST
|
detailSelectDialog.type === APP_LINK_TYPE_ENUM.PRODUCT_CATEGORY_LIST
|
||||||
@@ -232,7 +242,7 @@ function handleProductCategorySelected(id: number) {
|
|||||||
:parent-id="0"
|
:parent-id="0"
|
||||||
@update:model-value="handleProductCategorySelected"
|
@update:model-value="handleProductCategorySelected"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</ElFormItem>
|
||||||
</el-form>
|
</ElForm>
|
||||||
</el-dialog>
|
</DetailSelectModal>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -167,11 +167,13 @@ const setHeight = (item: HotZoneItemProperty, height: number) => {
|
|||||||
const activeHotZone = ref<HotZoneItemProperty>();
|
const activeHotZone = ref<HotZoneItemProperty>();
|
||||||
const appLinkDialogRef = ref();
|
const appLinkDialogRef = ref();
|
||||||
|
|
||||||
|
/** 显示 App 链接选择对话框 */
|
||||||
const handleShowAppLinkDialog = (hotZone: HotZoneItemProperty) => {
|
const handleShowAppLinkDialog = (hotZone: HotZoneItemProperty) => {
|
||||||
activeHotZone.value = hotZone;
|
activeHotZone.value = hotZone;
|
||||||
appLinkDialogRef.value.open(hotZone.url);
|
appLinkDialogRef.value.open(hotZone.url);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** 处理 App 链接选择变更 */
|
||||||
const handleAppLinkChange = (appLink: AppLink) => {
|
const handleAppLinkChange = (appLink: AppLink) => {
|
||||||
if (!appLink || !activeHotZone.value) {
|
if (!appLink || !activeHotZone.value) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
Reference in New Issue
Block a user