This commit is contained in:
Paidax
2025-11-06 15:33:35 +08:00
parent 2f9a27d2a0
commit 6efa654957
8 changed files with 456 additions and 474 deletions
@@ -34,41 +34,30 @@ const apps = {
<!-- 右侧内容 -->
<div class="tree-content">
<!-- 应用列表 -->
<div class="app-list" v-if="applications.length > 0">
<div
v-for="app in applications"
:key="app.id"
class="app-item"
@click="openApp(app)"
>
<div class="app-icon">
<van-image
v-if="app.picIcon"
:src="app.picIcon"
fit="cover"
width="40"
height="40"
radius="4"
></van-image>
<van-icon v-else-if="app.icon" :name="app.icon" size="24"></van-icon>
<van-icon v-else name="apps-o" size="24"></van-icon>
</div>
<div class="app-info">
<div class="app-title">{{ app.name }}</div>
<div class="app-desc" v-if="app.department">{{ app.department }}</div>
</div>
<div class="app-action">
<van-icon
:name="app.isFavorite ? 'star' : 'star-o'"
:class="['favorite-icon', app.isFavorite ? 'active' : '']"
@click.stop="toggleFavorite(app.id)"
></van-icon>
<div :class="['app-grid', { 'app-grid-single': applications.length === 1 }]"
v-if="applications.length > 0">
<div v-for="app in applications"
:key="app.id"
class="app-grid-item"
:class="{ 'is-favorite': app.isFavorite }"
@click="openApp(app)"
@touchstart="onTouchStart(app)"
@touchend="onTouchEnd"
@touchmove="onTouchMove">
<!-- 图标 -->
<div class="app-grid-icon">
<van-icon v-if="app.picIcon" :name="app.picIcon" size="64" style="border-radius: 12px; width: 64px; height: 64px;"></van-icon>
<van-icon v-else-if="app.icon" :name="app.icon" size="28"></van-icon>
<van-icon v-else name="apps-o" size="28"></van-icon>
</div>
<!-- 名称 -->
<div class="app-grid-name">{{ app.name }}</div>
</div>
</div>
</div>
<!-- 空状态 -->
<van-empty v-else description="暂无应用"></van-empty>
</div>
</div>
@@ -118,7 +107,10 @@ const apps = {
// 弹框相关
showMenuPopup: false,
currentApp: {},
currentMenus: []
currentMenus: [],
touchTimer: null,
isTouchMoved: false,
}
},
computed: {
@@ -129,8 +121,7 @@ const apps = {
// 当前选中的分类ID
currentCategoryId() {
return this.allCategories[this.activeTab]?.id || "all"
},
}
},
mounted() {
// 页面加载时获取分类和应用数据
@@ -225,16 +216,38 @@ const apps = {
.then((result) => {
if (result.code === 0) {
app.isFavorite = !app.isFavorite
this.$toast(app.isFavorite ? "收藏成功" : "取消收藏成功")
this.$toast(app.isFavorite ? ('收藏成功:' + app.name) : ('取消收藏:' + app.name))
} else {
console.error(app.isFavorite ? "取消收藏失败:" : "收藏失败:", result.msg)
console.error(app.isFavorite ? ('取消收藏:' + app.name) : ('收藏失败:' + app.name), result.msg)
}
})
.fail((error) => {
console.error(app.isFavorite ? "取消收藏异常:" : "收藏异常:", error)
console.error(app.isFavorite ? ('取消收藏:' + app.name) : ('收藏异常:' + app.name), error)
})
},
// 长按开始
onTouchStart(app) {
this.isTouchMoved = false
this.touchTimer = setTimeout(() => {
this.toggleFavorite(app.id)
}, 800) // 长按 800ms 触发
},
// 触摸移动(判断是否滑动,避免误触长按)
onTouchMove() {
this.isTouchMoved = true
},
// 触摸结束(清除计时器)
onTouchEnd() {
if (this.touchTimer) {
clearTimeout(this.touchTimer)
this.touchTimer = null
}
},
// 搜索
onSearch() {
this.applications = []
@@ -283,7 +296,7 @@ const apps = {
// 导航到菜单
navigateToMenu(menu) {
// 关闭弹框
this.showMenuPopup = false
// this.showMenuPopup = false
if (menu.href) {
if(menu.href.startsWith('http://') || menu.href.startsWith('https://')){
window.open(menu.href, '_blank')
@@ -295,6 +308,12 @@ const apps = {
}
}
},
// 初始加载消除长按收藏
beforeDestroy() {
if (this.touchTimer) {
clearTimeout(this.touchTimer)
}
},
style: /*language=CSS*/ `
.apps-container {
display: flex;
@@ -385,66 +404,77 @@ const apps = {
background: #fff;
}
.app-list {
flex: 1;
overflow-y: auto;
.app-grid {
display: grid;
/* 改为自适应列数:每格最小 80px,自动换行 */
grid-template-columns: repeat(auto-fit, minmax(80px, 1fr));
justify-items: center; /* 子项内容居中(图标和文字) */
justify-content: start; /* 整体网格靠左对齐,避免居中 */
gap: 12px;
padding: 12px;
background: #fff;
overflow-x: hidden;
}
.app-item {
.app-grid-single {
display: flex;
align-items: center;
padding: 12px 16px;
background-color: #fff;
margin-bottom: 1px;
position: relative;
justify-content: start;
padding: 16px 0;
}
.app-icon {
width: 40px;
height: 40px;
border-radius: 4px;
background-color: #f2f3f5;
.app-grid-single .app-grid-item {
max-width: 80px;
margin: 0 12px;
}
.app-grid-item {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
padding: 12px 4px;
border-radius: 8px;
background: #fff;
width: 100%;
max-width: 100%;
}
.app-grid-icon {
width: 64px;
height: 64px;
max-width: 64px;
max-height: 64px;
border-radius: 12px;
background: #f2f3f5;
display: flex;
align-items: center;
justify-content: center;
margin-right: 12px;
margin-bottom: 6px;
overflow: hidden;
border: 2px solid transparent;
transition: all 0.2s ease;
}
.app-info {
flex: 1;
}
.app-title {
font-size: 16px;
font-weight: 500;
margin-bottom: 4px;
color: #323233;
}
.app-desc {
.app-grid-name {
width: 100%;
font-size: 12px;
color: #969799;
}
.app-action {
padding: 0 8px;
}
.favorite-icon {
font-size: 20px;
color: #c8c9cc;
}
.favorite-icon.active {
color: #ff9800;
}
.loading-container {
padding: 20px 0;
color: #323233;
text-align: center;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.app-grid-item.is-favorite .app-grid-icon,
.app-grid-icon.is-favorite {
border-color: #ff9800;
box-shadow: 0 0 0 2px rgba(255, 152, 0, 0.2);
}
/* 菜单弹框样式 */
/deep/ .menu-popup {
height: 100%;
@@ -546,5 +576,6 @@ const apps = {
font-size: 16px;
color: #c8c9cc;
}
`
}