2024-08-02 11:02:22 +08:00
|
|
|
<template>
|
2024-10-08 19:58:21 +08:00
|
|
|
<Dialog v-model="dialogVisible" title="选择链接" width="65%">
|
|
|
|
<div class="h-500px flex gap-8px">
|
|
|
|
<!-- 左侧分组列表 -->
|
|
|
|
<el-scrollbar wrap-class="h-full" ref="groupScrollbar" view-class="flex flex-col">
|
|
|
|
<template v-for="(group, groupIndex) in APP_LINK_GROUP_LIST">
|
|
|
|
<el-button v-if="groupIndex<7" :key="groupIndex" :class="[
|
2024-08-02 11:02:22 +08:00
|
|
|
'm-r-16px m-l-0px! justify-start! w-90px',
|
|
|
|
{ active: activeGroup === group.name }
|
2024-10-08 19:58:21 +08:00
|
|
|
]" ref="groupBtnRefs" :text="activeGroup !== group.name"
|
|
|
|
:type="activeGroup === group.name ? 'primary' : 'default'" @click="handleGroupSelected(group.name)">
|
|
|
|
{{ group.name }}
|
|
|
|
</el-button>
|
|
|
|
</template>
|
|
|
|
</el-scrollbar>
|
|
|
|
<!-- 右侧链接列表 -->
|
|
|
|
<el-scrollbar class="h-full flex-1" @scroll="handleScroll" ref="linkScrollbar">
|
|
|
|
<div v-for="(group, groupIndex) in APP_LINK_GROUP_LIST" :key="groupIndex">
|
|
|
|
<template v-if="activeGroup == group.name && groupIndex<7">
|
|
|
|
<!-- 分组标题 -->
|
|
|
|
<div class="font-bold" ref="groupTitleRefs">{{ group.name }}</div>
|
|
|
|
<!-- 链接列表 -->
|
|
|
|
<el-tooltip v-for="(appLink, appLinkIndex) in group.links" :key="appLinkIndex"
|
|
|
|
:content="appLink.path" placement="bottom" :show-after="300">
|
|
|
|
|
|
|
|
<el-button class="m-b-8px m-r-8px m-l-0px!"
|
|
|
|
:type="isSameLink(appLink.path, activeAppLink.path) ? 'primary' : 'default'"
|
|
|
|
@click="handleAppLinkSelected(appLink)">
|
|
|
|
{{ appLink.name }}
|
|
|
|
</el-button>
|
|
|
|
</el-tooltip>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</el-scrollbar>
|
|
|
|
</div>
|
|
|
|
<!-- 底部对话框操作按钮 -->
|
|
|
|
<template #footer>
|
|
|
|
<el-button type="primary" @click="handleSubmit">确 定</el-button>
|
|
|
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
|
|
|
</template>
|
|
|
|
</Dialog>
|
|
|
|
<Dialog v-model="detailSelectDialog.visible" title="" width="50%">
|
|
|
|
<el-form class="min-h-200px">
|
|
|
|
<el-form-item label="选择分类" v-if="detailSelectDialog.type === APP_LINK_TYPE_ENUM.PRODUCT_CATEGORY_LIST">
|
|
|
|
<ProductCategorySelect v-model="detailSelectDialog.id" :parent-id="0"
|
|
|
|
@update:model-value="handleProductCategorySelected" />
|
|
|
|
</el-form-item>
|
|
|
|
</el-form>
|
|
|
|
</Dialog>
|
2024-08-02 11:02:22 +08:00
|
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
2024-10-08 19:58:21 +08:00
|
|
|
import { APP_LINK_GROUP_LIST, APP_LINK_TYPE_ENUM, AppLink } from './data'
|
|
|
|
import * as MemberStatisticsApi from '@/api/mall/statistics/member'
|
|
|
|
import { ButtonInstance, ScrollbarInstance } from 'element-plus'
|
|
|
|
import { split } from 'lodash-es'
|
|
|
|
import ProductCategorySelect from '@/views/mall/product/category/components/ProductCategorySelect.vue'
|
|
|
|
import { getUrlNumberValue } from '@/utils'
|
|
|
|
// 假设你要追加的数据是一个新的对象
|
|
|
|
const userComparison = ref([])
|
|
|
|
/** 查询会员用户数量对照卡片数据 */
|
|
|
|
const GetDiyPage = async () => {
|
|
|
|
userComparison.value = await MemberStatisticsApi.getDiyPage()
|
|
|
|
const arry = userComparison.value.map(link => {
|
|
|
|
return {
|
|
|
|
name: link.name,
|
|
|
|
path: `/pages/index/page?id=${link.id}`
|
|
|
|
};
|
|
|
|
});
|
|
|
|
userComparison.value = {
|
|
|
|
name: '自定义页面',
|
|
|
|
links:arry
|
|
|
|
}
|
|
|
|
APP_LINK_GROUP_LIST.push(userComparison.value);
|
|
|
|
// userComparison.value = APP_LINK_GROUP_LIST
|
|
|
|
// userComparison.value = APP_LINK_GROUP_LIST.push({qq:1})
|
|
|
|
console.log(APP_LINK_GROUP_LIST, 'userComparison.value')
|
|
|
|
}
|
|
|
|
GetDiyPage()
|
|
|
|
// APP 链接选择弹框
|
|
|
|
defineOptions({ name: 'AppLinkSelectDialog' })
|
|
|
|
// 选中的分组,默认选中第一个
|
|
|
|
const activeGroup = ref(APP_LINK_GROUP_LIST[0].name)
|
|
|
|
// 选中的 APP 链接
|
|
|
|
const activeAppLink = ref({} as AppLink)
|
2024-08-02 11:02:22 +08:00
|
|
|
|
2024-10-08 19:58:21 +08:00
|
|
|
/** 打开弹窗 */
|
|
|
|
const dialogVisible = ref(false)
|
|
|
|
const open = (link : string) => {
|
|
|
|
activeAppLink.value.path = link
|
|
|
|
dialogVisible.value = true
|
2024-08-02 11:02:22 +08:00
|
|
|
|
2024-10-08 19:58:21 +08:00
|
|
|
// 滚动到当前的链接
|
|
|
|
const group = APP_LINK_GROUP_LIST.find((group) =>
|
|
|
|
group.links.some((linkItem) => {
|
|
|
|
const sameLink = isSameLink(linkItem.path, link)
|
|
|
|
if (sameLink) {
|
|
|
|
activeAppLink.value = { ...linkItem, path: link }
|
|
|
|
}
|
|
|
|
return sameLink
|
|
|
|
})
|
|
|
|
)
|
|
|
|
if (group) {
|
|
|
|
// 使用 nextTick 的原因:可能 Dom 还没生成,导致滚动失败
|
|
|
|
nextTick(() => handleGroupSelected(group.name))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
defineExpose({ open })
|
2024-08-02 11:02:22 +08:00
|
|
|
|
2024-10-08 19:58:21 +08:00
|
|
|
// 处理 APP 链接选中
|
|
|
|
const handleAppLinkSelected = (appLink : AppLink) => {
|
|
|
|
if (!isSameLink(appLink.path, activeAppLink.value.path)) {
|
|
|
|
activeAppLink.value = appLink
|
|
|
|
console.log(activeAppLink.value,activeAppLink.value.path,"activeAppLink.value")
|
|
|
|
}
|
|
|
|
switch (appLink.type) {
|
|
|
|
case APP_LINK_TYPE_ENUM.PRODUCT_CATEGORY_LIST:
|
|
|
|
detailSelectDialog.value.visible = true
|
|
|
|
detailSelectDialog.value.type = appLink.type
|
|
|
|
// 返显
|
|
|
|
detailSelectDialog.value.id =
|
|
|
|
getUrlNumberValue('id', 'http://127.0.0.1' + activeAppLink.value.path) || undefined
|
|
|
|
break
|
|
|
|
default:
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
2024-08-02 11:02:22 +08:00
|
|
|
|
2024-10-08 19:58:21 +08:00
|
|
|
// 处理绑定值更新
|
|
|
|
const emit = defineEmits<{
|
|
|
|
change : [link: string]
|
|
|
|
appLinkChange : [appLink: AppLink]
|
|
|
|
}>()
|
|
|
|
const handleSubmit = () => {
|
|
|
|
dialogVisible.value = false
|
|
|
|
emit('change', activeAppLink.value.path)
|
|
|
|
emit('appLinkChange', activeAppLink.value)
|
|
|
|
}
|
2024-08-02 11:02:22 +08:00
|
|
|
|
2024-10-08 19:58:21 +08:00
|
|
|
// 分组标题引用列表
|
|
|
|
const groupTitleRefs = ref<HTMLInputElement[]>([])
|
|
|
|
/**
|
|
|
|
* 处理右侧链接列表滚动
|
|
|
|
* @param scrollTop 滚动条的位置
|
|
|
|
*/
|
|
|
|
const handleScroll = ({ scrollTop } : { scrollTop : number }) => {
|
|
|
|
const titleEl = groupTitleRefs.value.find((titleEl : HTMLInputElement) => {
|
|
|
|
// 获取标题的位置信息
|
|
|
|
const { offsetHeight, offsetTop } = titleEl
|
|
|
|
// 判断标题是否在可视范围内
|
|
|
|
return scrollTop >= offsetTop && scrollTop < offsetTop + offsetHeight
|
|
|
|
})
|
|
|
|
// 只需处理一次
|
|
|
|
if (titleEl && activeGroup.value !== titleEl.textContent) {
|
|
|
|
activeGroup.value = titleEl.textContent || ''
|
|
|
|
// 同步左侧的滚动条位置
|
|
|
|
scrollToGroupBtn(activeGroup.value)
|
|
|
|
}
|
|
|
|
}
|
2024-08-02 11:02:22 +08:00
|
|
|
|
2024-10-08 19:58:21 +08:00
|
|
|
// 右侧滚动条
|
|
|
|
const linkScrollbar = ref<ScrollbarInstance>()
|
|
|
|
// 处理分组选中
|
|
|
|
const handleGroupSelected = (group : string) => {
|
|
|
|
activeGroup.value = group
|
|
|
|
// const titleRef = groupTitleRefs.value.find((item: HTMLInputElement) => item.textContent === group)
|
|
|
|
// if (titleRef) {
|
|
|
|
// // 滚动分组标题
|
|
|
|
// linkScrollbar.value?.setScrollTop(titleRef.offsetTop)
|
|
|
|
// }
|
|
|
|
}
|
2024-08-02 11:02:22 +08:00
|
|
|
|
2024-10-08 19:58:21 +08:00
|
|
|
// 分组滚动条
|
|
|
|
const groupScrollbar = ref<ScrollbarInstance>()
|
|
|
|
// 分组引用列表
|
|
|
|
const groupBtnRefs = ref<ButtonInstance[]>([])
|
|
|
|
// 自动滚动分组按钮,确保分组按钮保持在可视区域内
|
|
|
|
const scrollToGroupBtn = (group : string) => {
|
|
|
|
const groupBtn = groupBtnRefs.value
|
|
|
|
.map((btn : ButtonInstance) => btn['ref'])
|
|
|
|
.find((ref : Node) => ref.textContent === group)
|
|
|
|
if (groupBtn) {
|
|
|
|
groupScrollbar.value?.setScrollTop(groupBtn.offsetTop)
|
|
|
|
}
|
|
|
|
}
|
2024-08-02 11:02:22 +08:00
|
|
|
|
2024-10-08 19:58:21 +08:00
|
|
|
// 是否为相同的链接(不比较参数,只比较链接)
|
|
|
|
const isSameLink = (link1 : string, link2 : string) => {
|
|
|
|
return split(link1, '?', 1)[0] === split(link2, '?', 1)[0]
|
|
|
|
}
|
2024-08-02 11:02:22 +08:00
|
|
|
|
2024-10-08 19:58:21 +08:00
|
|
|
// 详情选择对话框
|
|
|
|
const detailSelectDialog = ref<{
|
|
|
|
visible : boolean
|
|
|
|
id ?: number
|
|
|
|
type ?: APP_LINK_TYPE_ENUM
|
|
|
|
}>({
|
|
|
|
visible: false,
|
|
|
|
id: undefined,
|
|
|
|
type: undefined
|
|
|
|
})
|
|
|
|
// 处理详情选择
|
|
|
|
const handleProductCategorySelected = (id : number) => {
|
|
|
|
const url = new URL(activeAppLink.value.path, 'http://127.0.0.1')
|
|
|
|
// 修改 id 参数
|
|
|
|
url.searchParams.set('id', `${id}`)
|
|
|
|
// 排除域名
|
|
|
|
activeAppLink.value.path = `${url.pathname}${url.search}`
|
|
|
|
// 关闭对话框
|
|
|
|
detailSelectDialog.value.visible = false
|
|
|
|
// 重置 id
|
|
|
|
detailSelectDialog.value.id = undefined
|
|
|
|
}
|
2024-08-02 11:02:22 +08:00
|
|
|
</script>
|
2024-10-08 19:58:21 +08:00
|
|
|
<style lang="scss" scoped></style>
|