..
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
const apps = {
|
||||
template: /*language=HTML*/ `
|
||||
<div class="apps-container">
|
||||
<van-nav-bar title="代表阅览" placeholder fixed></van-nav-bar>
|
||||
<van-nav-bar title="应用中心" placeholder fixed></van-nav-bar>
|
||||
<!-- 搜索栏 -->
|
||||
<van-sticky offset-top="46px">
|
||||
<van-search
|
||||
@@ -13,14 +13,25 @@ const apps = {
|
||||
></van-search>
|
||||
</van-sticky>
|
||||
|
||||
<!-- 使用TreeSelect组件 -->
|
||||
<van-tree-select
|
||||
:items="treeSelectItems"
|
||||
:main-active-index.sync="activeTab"
|
||||
@click-nav="onClickNav"
|
||||
>
|
||||
<template #content>
|
||||
<div class="custom-tree-select">
|
||||
<!-- 左侧导航 -->
|
||||
<div class="tree-nav">
|
||||
<div
|
||||
v-for="(category, index) in allCategories"
|
||||
:key="category.id"
|
||||
:class="['nav-item', { active: activeTab === index }]"
|
||||
@click="onClickNav(index)"
|
||||
>
|
||||
<div class="nav-icon" v-if="category.icon">
|
||||
<i :class="category.icon"></i>
|
||||
</div>
|
||||
<div class="nav-text">{{ category.name }}</div>
|
||||
<div class="nav-indicator" v-if="activeTab === index"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧内容 -->
|
||||
<div class="tree-content">
|
||||
<!-- 应用列表 -->
|
||||
<div class="app-list" v-if="applications.length > 0">
|
||||
<div
|
||||
@@ -50,15 +61,39 @@ const apps = {
|
||||
:name="app.isFavorite ? 'star' : 'star-o'"
|
||||
:class="['favorite-icon', app.isFavorite ? 'active' : '']"
|
||||
@click.stop="toggleFavorite(app.id)"
|
||||
/>
|
||||
></van-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<van-empty v-else description="暂无应用"></van-empty>
|
||||
</template>
|
||||
</van-tree-select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 应用菜单弹框 -->
|
||||
<van-popup v-model="showMenuPopup" position="bottom" :style="{ width: '100%', maxHeight: '60%' }" round>
|
||||
<div class="menu-popup">
|
||||
<div class="popup-header">
|
||||
<div class="popup-title">{{ currentApp.name }}</div>
|
||||
<van-icon name="cross" @click="showMenuPopup = false" class="close-icon"></van-icon>
|
||||
</div>
|
||||
<div class="menu-grid">
|
||||
<div
|
||||
v-for="menu in currentMenus"
|
||||
:key="menu.id"
|
||||
class="grid-item"
|
||||
@click="navigateToMenu(menu)"
|
||||
>
|
||||
<div class="grid-icon">
|
||||
<van-icon :name="menu.icon || 'apps-o'" size="24"></van-icon>
|
||||
</div>
|
||||
<div class="grid-name">{{ menu.name }}</div>
|
||||
<div class="grid-desc" v-if="menu.aliasName">{{ menu.aliasName }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</van-popup>
|
||||
</div>
|
||||
`,
|
||||
data() {
|
||||
@@ -67,9 +102,9 @@ const apps = {
|
||||
applications: [],
|
||||
// 固定分类列表
|
||||
categories: [
|
||||
{id: "all", name: "全部应用", icon: "apps-o"},
|
||||
{id: "favorites", name: "我的收藏", icon: "star-o"},
|
||||
{id: "recommended", name: "推荐应用", icon: "like-o"}
|
||||
{id: "all", name: "全部应用", icon: "fa fa-th-large"},
|
||||
{id: "favorites", name: "我的收藏", icon: "fa fa-star-o"},
|
||||
{id: "recommended", name: "推荐应用", icon: "fa fa-thumbs-o-up"}
|
||||
],
|
||||
// 动态加载的分类
|
||||
dynamicCategories: [],
|
||||
@@ -78,7 +113,11 @@ const apps = {
|
||||
// 搜索关键词
|
||||
searchKeyword: "",
|
||||
// 列表相关
|
||||
loading: true
|
||||
loading: true,
|
||||
// 弹框相关
|
||||
showMenuPopup: false,
|
||||
currentApp: {},
|
||||
currentMenus: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -90,13 +129,7 @@ const apps = {
|
||||
currentCategoryId() {
|
||||
return this.allCategories[this.activeTab]?.id || "all"
|
||||
},
|
||||
// TreeSelect组件所需的数据格式
|
||||
treeSelectItems() {
|
||||
return this.allCategories.map(category => ({
|
||||
text: category.name,
|
||||
className: 'category-item'
|
||||
}))
|
||||
}
|
||||
|
||||
},
|
||||
mounted() {
|
||||
// 页面加载时获取分类和应用数据
|
||||
@@ -106,17 +139,13 @@ const apps = {
|
||||
methods: {
|
||||
// 加载分类数据
|
||||
loadCategories() {
|
||||
$.get("/platform/v4/apps/categories", {platform: "H5"})
|
||||
.then((result) => {
|
||||
if (result.code === 0) {
|
||||
this.dynamicCategories = result.data || []
|
||||
} else {
|
||||
console.error("获取应用分类失败:", result.msg)
|
||||
}
|
||||
})
|
||||
.fail((error) => {
|
||||
console.error("获取应用分类异常:", error)
|
||||
})
|
||||
this.$axios.post("/platform/v4/apps/categories", {platform: "H5"}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.dynamicCategories = res.data || []
|
||||
} else {
|
||||
console.error("获取应用分类失败:", res.msg)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 加载应用数据
|
||||
@@ -147,24 +176,19 @@ const apps = {
|
||||
|
||||
// 如果是"推荐应用"分类
|
||||
if (this.currentCategoryId === "recommended") {
|
||||
$.get("/platform/v4/apps/recommended")
|
||||
.then((result) => {
|
||||
if (result.code === 0) {
|
||||
this.applications = result.data.list || []
|
||||
} else {
|
||||
console.error("获取推荐应用失败:", result.msg)
|
||||
}
|
||||
this.loading = false
|
||||
})
|
||||
.fail((error) => {
|
||||
console.error("获取推荐应用异常:", error)
|
||||
this.loading = false
|
||||
})
|
||||
this.$axios.post("/platform/v4/apps/recommended").then((result) => {
|
||||
if (result.code === 0) {
|
||||
this.applications = result.data.list || []
|
||||
} else {
|
||||
console.error("获取推荐应用失败:", result.msg)
|
||||
}
|
||||
this.loading = false
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 发送请求获取普通应用列表
|
||||
$.get("/platform/v4/apps/list?" + queryString)
|
||||
this.$axios.post("/platform/v4/apps/list?" + queryString)
|
||||
.then((result) => {
|
||||
if (result.code === 0) {
|
||||
this.applications = result.data || []
|
||||
@@ -173,15 +197,11 @@ const apps = {
|
||||
}
|
||||
this.loading = false
|
||||
})
|
||||
.fail((error) => {
|
||||
console.error("获取应用列表异常:", error)
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
|
||||
// 加载收藏的应用
|
||||
loadFavorites() {
|
||||
$.get("/platform/v4/apps/favorite")
|
||||
this.$axios.post("/platform/v4/apps/favorite")
|
||||
.then((result) => {
|
||||
if (result.code === 0) {
|
||||
this.applications = result.data || []
|
||||
@@ -190,10 +210,6 @@ const apps = {
|
||||
}
|
||||
this.loading = false
|
||||
})
|
||||
.fail((error) => {
|
||||
console.error("获取收藏应用异常:", error)
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
|
||||
// 切换应用收藏状态
|
||||
@@ -239,10 +255,48 @@ const apps = {
|
||||
|
||||
// 打开应用
|
||||
openApp(app) {
|
||||
// 储存到缓存
|
||||
window.sessionStorage.setItem("zhgh_sub_app", JSON.stringify(app))
|
||||
// 新标签页打开
|
||||
window.open("/platform/v4/subApp?appId=" + app.id, "_blank")
|
||||
this.$axios.post("/platform/sys/user/subAppMenus", {appId: app.id}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.showAppMenus(app, res.data)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 显示应用菜单弹框
|
||||
showAppMenus(app, menus) {
|
||||
if (!menus || menus.length === 0) {
|
||||
this.$toast('该应用暂无可用功能')
|
||||
return
|
||||
}
|
||||
|
||||
// 如果只有一个菜单项,直接跳转
|
||||
if (menus.length === 1) {
|
||||
this.navigateToMenu(menus[0])
|
||||
return
|
||||
}
|
||||
|
||||
// 多个菜单项时显示popup弹框
|
||||
this.currentApp = app
|
||||
this.currentMenus = menus
|
||||
this.showMenuPopup = true
|
||||
},
|
||||
|
||||
// 导航到菜单
|
||||
navigateToMenu(menu) {
|
||||
// 关闭弹框
|
||||
this.showMenuPopup = false
|
||||
|
||||
if (menu.href) {
|
||||
// 如果是H5平台,直接跳转
|
||||
if (menu.platform === 'H5') {
|
||||
window.location.href = menu.href
|
||||
} else {
|
||||
// 其他平台可能需要特殊处理
|
||||
window.open(menu.href, '_blank')
|
||||
}
|
||||
} else {
|
||||
this.$toast('该功能暂不可用')
|
||||
}
|
||||
}
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
@@ -252,20 +306,81 @@ const apps = {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.van-tree-select {
|
||||
height: calc(100vh - 150px) !important;
|
||||
/* 自定义树形选择组件样式 */
|
||||
.custom-tree-select {
|
||||
display: flex;
|
||||
height: calc(100vh - 150px);
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.van-tree-select__nav {
|
||||
.tree-nav {
|
||||
flex: 0 0 90px;
|
||||
background: #f7f8fa;
|
||||
border-right: 1px solid #ebedf0;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.van-tree-select__content {
|
||||
padding: 0;
|
||||
.nav-item {
|
||||
position: relative;
|
||||
padding: 12px 8px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
border-bottom: 1px solid #ebedf0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.category-item {
|
||||
font-size: 14px;
|
||||
.nav-item:hover {
|
||||
background: #f2f3f5;
|
||||
}
|
||||
|
||||
.nav-item.active {
|
||||
background: #fff;
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
.nav-item.active::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 3px;
|
||||
background: #1989fa;
|
||||
}
|
||||
|
||||
.nav-icon {
|
||||
font-size: 18px;
|
||||
margin-bottom: 6px;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.nav-text {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
text-align: center;
|
||||
line-height: 1.2;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.nav-indicator {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 6px solid #1989fa;
|
||||
border-top: 6px solid transparent;
|
||||
border-bottom: 6px solid transparent;
|
||||
}
|
||||
|
||||
.tree-content {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.app-list {
|
||||
@@ -327,5 +442,107 @@ const apps = {
|
||||
padding: 20px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 菜单弹框样式 */
|
||||
::v-deep .menu-popup {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
::v-deep .popup-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 16px 20px;
|
||||
border-bottom: 1px solid #ebedf0;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
::v-deep .popup-title {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #323233;
|
||||
}
|
||||
|
||||
::v-deep .close-icon {
|
||||
font-size: 18px;
|
||||
color: #969799;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
::v-deep .menu-grid {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
|
||||
::v-deep .grid-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 20px 12px;
|
||||
background: #fff;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
::v-deep .grid-item:active {
|
||||
transform: scale(0.95);
|
||||
background: #f2f3f5;
|
||||
}
|
||||
|
||||
::v-deep .grid-icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 12px;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 12px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
::v-deep .grid-name {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #323233;
|
||||
text-align: center;
|
||||
margin-bottom: 4px;
|
||||
line-height: 1.2;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 100%;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
::v-deep .grid-desc {
|
||||
font-size: 12px;
|
||||
color: #969799;
|
||||
text-align: center;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
::v-deep .menu-name {
|
||||
font-size: 16px;
|
||||
color: #323233;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
::v-deep .menu-desc {
|
||||
font-size: 12px;
|
||||
color: #969799;
|
||||
}
|
||||
|
||||
::v-deep .menu-arrow {
|
||||
font-size: 16px;
|
||||
color: #c8c9cc;
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user