635 lines
18 KiB
HTML
635 lines
18 KiB
HTML
<!--#
|
|
layout("/layouts/v4/baseLayout.html"){
|
|
#-->
|
|
|
|
<style>
|
|
.apps-hero {
|
|
position: relative;
|
|
overflow: hidden;
|
|
display: flex;
|
|
align-items: center;
|
|
/*border-radius: 8px 8px 0 0;*/
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.apps-hero img {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
.apps-container {
|
|
display: flex;
|
|
/*height: calc(100vh - 64px - 48px - 180px);*/
|
|
background-color: #fff;
|
|
/*border-radius: 0 0 8px 8px;*/
|
|
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
|
|
overflow: hidden;
|
|
flex: 1;
|
|
}
|
|
|
|
.apps-sidebar {
|
|
width: 220px;
|
|
background-color: #f7f7f7;
|
|
border-right: 1px solid #e8e8e8;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.apps-sidebar-item {
|
|
padding: 16px 20px;
|
|
cursor: pointer;
|
|
transition: all 0.3s;
|
|
font-size: 16px;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
}
|
|
|
|
.apps-sidebar-item.active {
|
|
background-color: #e6f7ff;
|
|
color: var(--color-primary);
|
|
border-right: 2px solid #1890ff;
|
|
}
|
|
|
|
.apps-sidebar-item:hover:not(.active) {
|
|
background-color: #f0f0f0;
|
|
}
|
|
|
|
.apps-sidebar-item i{
|
|
min-width: 22px;
|
|
}
|
|
|
|
.apps-content {
|
|
flex: 1;
|
|
padding: 20px;
|
|
overflow: auto;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.apps-header {
|
|
padding: 0 0 20px 0;
|
|
border-bottom: 1px solid #eee;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.apps-search-container {
|
|
display: flex;
|
|
align-items: center;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.apps-search {
|
|
position: relative;
|
|
width: 400px;
|
|
}
|
|
|
|
.apps-search input {
|
|
width: 100%;
|
|
height: 36px;
|
|
border: 1px solid #dcdfe6;
|
|
border-radius: 4px;
|
|
padding: 0 15px;
|
|
font-size: 14px;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.apps-search .search-icon {
|
|
position: absolute;
|
|
right: 10px;
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
color: #999;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.apps-filter {
|
|
margin-top: 20px;
|
|
}
|
|
|
|
.apps-filter-title {
|
|
color: #666;
|
|
font-size: 14px;
|
|
margin-bottom: 5px;
|
|
}
|
|
|
|
.apps-filter-tags {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 10px;
|
|
}
|
|
|
|
.filter-tag {
|
|
padding: 5px 15px;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
font-size: 14px;
|
|
transition: all 0.3s;
|
|
}
|
|
|
|
.filter-tag.active {
|
|
background-color: var(--color-primary);
|
|
color: #fff;
|
|
}
|
|
|
|
.filter-tag:not(.active) {
|
|
background-color: #f0f0f0;
|
|
color: #333;
|
|
}
|
|
|
|
.filter-tag:not(.active):hover {
|
|
background-color: #e0e0e0;
|
|
}
|
|
|
|
.apps-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
|
gap: 20px;
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
grid-auto-rows: min-content;
|
|
padding-top: 5px;
|
|
}
|
|
|
|
.app-card {
|
|
border: 1px solid #e8e8e8;
|
|
border-radius: 8px;
|
|
overflow: hidden;
|
|
transition: all 0.3s;
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 15px;
|
|
position: relative;
|
|
}
|
|
|
|
.app-card:hover {
|
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
transform: translateY(-2px);
|
|
cursor: pointer;
|
|
}
|
|
|
|
.app-icon {
|
|
width: 48px;
|
|
height: 48px;
|
|
border-radius: 8px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
margin-right: 15px;
|
|
color: #fff;
|
|
font-size: 24px;
|
|
}
|
|
|
|
.app-icon img {
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: cover;
|
|
border-radius: 8px;
|
|
}
|
|
|
|
.app-icon i {
|
|
color: var(--color-primary);
|
|
font-size: 38px;
|
|
}
|
|
|
|
.favorite-icon {
|
|
position: absolute;
|
|
bottom: 10px;
|
|
right: 10px;
|
|
cursor: pointer;
|
|
transition: all 0.3s;
|
|
font-size: 18px;
|
|
color: #c0c4cc;
|
|
}
|
|
|
|
.favorite-icon.active {
|
|
color: #ff9800;
|
|
}
|
|
|
|
.favorite-icon:hover {
|
|
transform: scale(1.2);
|
|
}
|
|
|
|
.app-info {
|
|
flex: 1;
|
|
}
|
|
|
|
.app-title {
|
|
font-weight: 500;
|
|
margin-bottom: 5px;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.app-desc {
|
|
color: #999;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.alphabet-filter {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 5px;
|
|
}
|
|
|
|
.alphabet-item {
|
|
width: 30px;
|
|
height: 30px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
transition: all 0.3s;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.alphabet-item.active {
|
|
background-color: var(--color-primary);
|
|
color: #fff;
|
|
}
|
|
|
|
.alphabet-item:not(.active) {
|
|
background-color: #f0f0f0;
|
|
}
|
|
|
|
.alphabet-item:hover:not(.active) {
|
|
background-color: #e0e0e0;
|
|
}
|
|
|
|
.app-status {
|
|
position: absolute;
|
|
top: 0;
|
|
right: 0;
|
|
background-color: #ff9800;
|
|
color: #fff;
|
|
padding: 2px 10px;
|
|
font-size: 12px;
|
|
border-bottom-left-radius: 8px;
|
|
}
|
|
|
|
.apps-wrapper {
|
|
/*margin: 0 auto;*/
|
|
/*margin: 24px;*/
|
|
/*padding: 24px;*/
|
|
display: flex;
|
|
flex-direction: column;
|
|
height: calc(100vh - 64px);
|
|
}
|
|
|
|
.no-results {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
min-height: 300px;
|
|
padding: 40px 20px;
|
|
}
|
|
|
|
.no-results-content {
|
|
text-align: center;
|
|
max-width: 300px;
|
|
}
|
|
|
|
.no-results i {
|
|
color: #c0c4cc;
|
|
margin-bottom: 16px;
|
|
}
|
|
|
|
.no-results .title {
|
|
font-size: 16px;
|
|
color: #606266;
|
|
font-weight: 500;
|
|
margin-bottom: 8px;
|
|
}
|
|
|
|
.no-results .hint {
|
|
font-size: 14px;
|
|
color: #909399;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.page-item.disabled {
|
|
color: #c0c4cc;
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
.page-item.disabled:hover {
|
|
border-color: #d9d9d9;
|
|
color: #c0c4cc;
|
|
}
|
|
|
|
.loading-container {
|
|
text-align: center;
|
|
padding: 40px 0;
|
|
color: #909399;
|
|
font-size: 14px;
|
|
}
|
|
</style>
|
|
|
|
<div class="apps-wrapper" id="app">
|
|
<div class="apps-hero">
|
|
<img src="/assets/platform/img/v4/yyzx.png" alt="应用中心" />
|
|
</div>
|
|
|
|
<div class="apps-container">
|
|
<!-- Left Sidebar -->
|
|
<div class="apps-sidebar">
|
|
<div
|
|
v-for="category in allCategories"
|
|
:key="category.id"
|
|
:class="['apps-sidebar-item', activeCategory === category.id ? 'active' : '']"
|
|
@click="changeCategory(category.id)"
|
|
>
|
|
<i :class="category.icon"></i>
|
|
{{ category.name }}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Main Content -->
|
|
<div class="apps-content">
|
|
<div class="apps-header">
|
|
<div class="apps-search-container">
|
|
<div class="apps-search">
|
|
<input type="text" v-model="searchKeyword" @keyup.enter="search" placeholder="请输入内容" />
|
|
<i class="el-icon-search search-icon" @click="search"></i>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 字母过滤 -->
|
|
<div class="apps-filter">
|
|
<div class="apps-filter-title">首字母:</div>
|
|
<div class="apps-filter-tags alphabet-filter">
|
|
<div :class="['filter-tag', activeAlphabet === '' ? 'active' : '']" @click="changeAlphabet('')">全部</div>
|
|
<div
|
|
v-for="letter in alphabets"
|
|
:key="letter"
|
|
:class="['alphabet-item', activeAlphabet === letter ? 'active' : '']"
|
|
@click="changeAlphabet(letter)"
|
|
>
|
|
{{ letter }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 应用网格 -->
|
|
<div class="apps-grid" v-if="applications.length > 0">
|
|
<div v-for="app in applications" :key="app.id" class="app-card" @click.stop="openApp(app)">
|
|
<div :class="['app-icon', app.iconType]">
|
|
<i v-if="app.icon && !app.picIcon" :class="app.icon"></i>
|
|
<img v-else-if="app.picIcon" :src="app.picIcon" :alt="app.name || ''" />
|
|
<i v-else class="fa fa-skype"></i>
|
|
</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-status" v-if="app.status">{{ app.status }}</div>
|
|
<div
|
|
:class="['favorite-icon', app.isFavorite ? 'active' : '']"
|
|
@click.stop="toggleFavorite(app.id)"
|
|
:title="app.isFavorite ? '取消收藏' : '收藏'"
|
|
>
|
|
<i :class="app.isFavorite ? 'el-icon-star-on' : 'el-icon-star-off'"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 加载状态 -->
|
|
<div class="loading-container" v-if="loading">
|
|
<i class="el-icon-loading"></i>
|
|
<p>加载中...</p>
|
|
</div>
|
|
|
|
<!-- 无搜索结果 -->
|
|
<div class="no-results" v-else-if="applications.length === 0">
|
|
<div class="no-results-content">
|
|
<i class="el-icon-document" style="font-size: 48px"></i>
|
|
<p class="title">没有找到匹配的应用</p>
|
|
<p class="hint">请尝试不同的搜索词或筛选条件</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
new Vue({
|
|
el: "#app",
|
|
data: {
|
|
// 应用列表
|
|
applications: [],
|
|
// 分类列表
|
|
categories: [
|
|
{ id: "all", name: "全部应用", icon: "fa fa-th-large" },
|
|
{ id: "favorites", name: "我的收藏", icon: "fa fa-star" },
|
|
{ id: "recommended", name: "推荐应用", icon: "fa fa-thumbs-up" }
|
|
],
|
|
// 动态加载的分类
|
|
dynamicCategories: [],
|
|
// 当前选中的分类
|
|
activeCategory: "all",
|
|
// 字母表筛选
|
|
alphabets: [
|
|
"A",
|
|
"B",
|
|
"C",
|
|
"D",
|
|
"E",
|
|
"F",
|
|
"G",
|
|
"H",
|
|
"I",
|
|
"J",
|
|
"K",
|
|
"L",
|
|
"M",
|
|
"N",
|
|
"O",
|
|
"P",
|
|
"Q",
|
|
"R",
|
|
"S",
|
|
"T",
|
|
"U",
|
|
"V",
|
|
"W",
|
|
"X",
|
|
"Y",
|
|
"Z"
|
|
],
|
|
activeAlphabet: "",
|
|
// 搜索关键词
|
|
searchKeyword: "",
|
|
// 分页相关
|
|
currentPage: 1,
|
|
pageSize: 15,
|
|
totalPage: 1,
|
|
total: 0,
|
|
// 加载状态
|
|
loading: true
|
|
},
|
|
computed: {
|
|
// 所有分类(固定分类 + 动态分类)
|
|
allCategories() {
|
|
return [...this.categories, ...this.dynamicCategories]
|
|
}
|
|
},
|
|
mounted() {
|
|
// 页面加载时获取分类和应用数据
|
|
this.loadCategories()
|
|
this.loadApps()
|
|
},
|
|
methods: {
|
|
// 加载分类数据
|
|
loadCategories() {
|
|
$.get("/platform/v4/apps/categories")
|
|
.then((result) => {
|
|
if (result.code === 0) {
|
|
this.dynamicCategories = result.data || []
|
|
} else {
|
|
console.error("获取应用分类失败:", result.msg)
|
|
}
|
|
})
|
|
.fail((error) => {
|
|
console.error("获取应用分类异常:", error)
|
|
})
|
|
},
|
|
|
|
// 加载应用数据
|
|
loadApps() {
|
|
this.loading = true
|
|
|
|
// 构建请求参数
|
|
const params = {
|
|
categoryId:
|
|
this.activeCategory === "all"
|
|
? ""
|
|
: this.activeCategory === "favorites" || this.activeCategory === "recommended"
|
|
? this.activeCategory
|
|
: this.activeCategory,
|
|
letter: this.activeAlphabet,
|
|
keyword: this.searchKeyword
|
|
}
|
|
|
|
// 将参数转换为URL查询参数
|
|
const queryString = Object.keys(params)
|
|
.filter((key) => params[key] !== null && params[key] !== undefined && params[key] !== "")
|
|
.map((key) => encodeURIComponent(key) + "=" + encodeURIComponent(params[key]))
|
|
.join("&")
|
|
|
|
// 如果是"我的收藏"分类
|
|
if (this.activeCategory === "favorites") {
|
|
this.loadFavorites()
|
|
return
|
|
}
|
|
|
|
// 如果是"推荐应用"分类
|
|
if (this.activeCategory === "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
|
|
})
|
|
return
|
|
}
|
|
|
|
// 发送请求获取普通应用列表
|
|
$.get("/platform/v4/apps/list?" + queryString)
|
|
.then((result) => {
|
|
if (result.code === 0) {
|
|
this.applications = result.data || []
|
|
} else {
|
|
console.error("获取应用列表失败:", result.msg)
|
|
}
|
|
this.loading = false
|
|
})
|
|
.fail((error) => {
|
|
console.error("获取应用列表异常:", error)
|
|
this.loading = false
|
|
})
|
|
},
|
|
|
|
// 加载收藏的应用
|
|
loadFavorites() {
|
|
$.get("/platform/v4/apps/favorite")
|
|
.then((result) => {
|
|
if (result.code === 0) {
|
|
this.applications = result.data || []
|
|
} else {
|
|
console.error("获取收藏应用失败:", result.msg)
|
|
}
|
|
})
|
|
.fail((error) => {
|
|
console.error("获取收藏应用异常:", error)
|
|
})
|
|
},
|
|
|
|
// 切换应用收藏状态
|
|
toggleFavorite(appId) {
|
|
const app = this.applications.find((a) => a.id === appId)
|
|
if (!app) return
|
|
|
|
const url = app.isFavorite ? "/platform/v4/apps/removeFavorite" : "/platform/v4/apps/addFavorite"
|
|
const params = { appId: appId }
|
|
|
|
$.post(url, params)
|
|
.then((result) => {
|
|
if (result.code === 0) {
|
|
app.isFavorite = !app.isFavorite
|
|
this.$message.success(app.isFavorite ? "收藏成功" : "取消收藏成功")
|
|
} else {
|
|
console.error(app.isFavorite ? "取消收藏失败:" : "收藏失败:", result.msg)
|
|
}
|
|
})
|
|
.fail((error) => {
|
|
console.error(app.isFavorite ? "取消收藏异常:" : "收藏异常:", error)
|
|
})
|
|
},
|
|
|
|
// 切换应用分类
|
|
changeCategory(categoryId) {
|
|
this.activeCategory = categoryId
|
|
this.currentPage = 1
|
|
|
|
// 如果是"我的收藏"分类
|
|
if (categoryId === "favorites") {
|
|
this.loadFavorites()
|
|
} else {
|
|
this.loadApps()
|
|
}
|
|
},
|
|
|
|
// 切换应用字母
|
|
changeAlphabet(letter) {
|
|
this.activeAlphabet = letter
|
|
this.currentPage = 1
|
|
this.loadApps()
|
|
},
|
|
|
|
// 搜索
|
|
search() {
|
|
this.loadApps()
|
|
},
|
|
|
|
// 打开应用
|
|
openApp(app) {
|
|
// 储存到缓存
|
|
window.sessionStorage.setItem("zhgh_sub_app", JSON.stringify(app))
|
|
// 新标签页打开
|
|
window.open("/platform/v4/subApp?appId=" + app.id, "_blank")
|
|
}
|
|
}
|
|
})
|
|
</script>
|
|
|
|
<!--#
|
|
}
|
|
#-->
|