2026-05-09 10:34:51 +08:00

315 lines
6.9 KiB
Vue

<script setup lang="ts">
import { $sleep, isNotStudyMachine, isStudyMachine } from '@/utils'
import { useRouter } from 'vue-router'
import { openBridge, getManufacturer, $XXL } from '@/utils'
import { globalStore } from '@/stores'
import { systemApps, aiApps, expandApps, infantApps } from './app'
import { storeToRefs } from 'pinia'
import { useTips } from '@/hooks'
import { debounce } from 'lodash-es'
const OSS_URL = `${import.meta.env.VITE_OSS_URL}`
const app_bg = `url(${OSS_URL}/urm/app_bg.png) bottom/contain no-repeat`
// const pattern = `url(${OSS_URL}/urm/subject_item_pattern.svg) left/cover no-repeat`;
// 用户信息
// const { userInfo } = storeToRefs(userStore())
const router = useRouter()
const activeClass = ref(0)
const classList = computed(() =>
[
{
id: 0,
name: '系统',
},
{
id: 1,
name: '其他',
show: otherApps.value.length > 0,
},
{
id: 2,
name: 'AI学习',
},
{
id: 3,
name: '素质拓展',
},
{
id: 4,
name: '幼儿',
},
].filter(i => i.show !== false),
)
const { system, otherApps } = storeToRefs(globalStore())
const { getApps } = globalStore()
async function onBarChange(item: anyObj) {
if (activeClass.value === 1) {
init()
}
// taskList.value = item.taskActivityVoList;
}
const appList = computed(() => {
let app = [] as any[]
if (isNotStudyMachine) return app
switch (activeClass.value) {
case 0:
if (getManufacturer() === 'M10') {
systemApps.forEach(i => {
if (i.appName === '相机') {
i.pkName = 'com.mediatek.camera'
}
})
}
if (!system.value.debug) {
app = systemApps.filter(
i => !['com.android.settings', 'com.android.documentsui'].includes(i.pkName),
)
} else {
app = systemApps
}
break
case 1:
app = otherApps.value
break
case 2:
app = aiApps
break
case 3:
app = expandApps
break
case 4:
app = infantApps
break
}
return app
})
const loading = ref(true)
if (isStudyMachine) {
init()
}
function init() {
if (system.value.apps.length === 0) {
loading.value = true
}
getApps().finally(() => {
loading.value = false
})
}
const canShow = ref(false)
onMounted(async () => {
if (isStudyMachine) await $sleep(300)
canShow.value = true
})
onActivated(async () => {
if (isNotStudyMachine) return router.push('/')
init()
})
function onOpen(item: anyObj) {
if (item.href) {
// window.location.href = item.href;
$XXL.openExternalURL(item.href)
return
}
if (item.path) {
router.push(item.path)
return
}
openBridge(
'app',
JSON.stringify({
pkg: item.pkName,
cls: item.cls,
extra: item.extra,
}),
)
}
const onUninstall = debounce(
(data: anyObj) => {
if (activeClass.value !== 1) return
if (data.href) return
useTips({
title: '卸载应用',
html: `确定要卸载【${data.appName}】吗?`,
showCancel: false,
onOk: async () => {
$XXL.uninstallApp(data.pkName)
loading.value = true
await $sleep(300)
getApps().finally(() => {
loading.value = false
})
},
})
},
500,
{
leading: true,
trailing: false,
},
)
// 开放素养课程
// 只有黔西南州勤智学校才显示
// const openCourseBtnVisible = computed(() => {
// return (
// userInfo.value.schoolPersonType !== 1 &&
// ['黔西南州勤智学校'].includes(userInfo.value.schoolName) &&
// activeClass.value === 3
// )
// })
// function openCourse() {
// window.$xxl.installApkFromURL('http://124.223.42.69/jxwgb_newyouer_video.apk')
// }
</script>
<template>
<div class="page">
<BackBar leftText="应用" />
<div v-if="canShow" class="content">
<div class="left">
<Sidebar
v-model="activeClass"
:config="classList"
class="left-vbar"
@handle-change="onBarChange"
></Sidebar>
</div>
<div
:class="{
right: true,
bigIcon: activeClass !== 1,
}"
>
<!-- <div v-if="!loading && openCourseBtnVisible" class="open-course-div">
<el-button type="primary" size="large" @click="openCourse">开放素养课程</el-button>
</div> -->
<Empty v-if="loading" type="loading" />
<el-scrollbar v-else>
<div class="list">
<div
v-for="item in appList"
:key="item.pkName"
v-longpress="() => onUninstall(item)"
class="item"
@click="onOpen(item)"
>
<img :src="item.iconPath" />
<div class="title">
<div :class="{ name: true, small: item.appName.length > 6 }">
{{ item.appName }}
</div>
</div>
</div>
</div>
</el-scrollbar>
</div>
</div>
<Empty v-else type="loading" />
</div>
</template>
<style lang="scss" scoped>
.page {
width: 100%;
height: 100%;
padding: $space-4_h $space-6;
@include main_bg;
.content {
width: 100%;
height: calc(100% - 80px - 52px);
display: flex;
.left {
width: 260px;
height: 100%;
margin-right: $space-8;
flex-shrink: 0;
margin-top: 4.33vh;
&-vbar {
height: 100%;
position: static;
}
}
.right {
flex: 1;
// width: calc(100% - 340px);
height: 100%;
.list {
width: 100%;
height: calc(100% - 80px);
display: grid;
grid-template-columns: repeat(4, 346px);
grid-auto-rows: 304px;
gap: $space-5 $space-3;
.item {
border-radius: $radius-5;
overflow: hidden;
position: relative;
display: flex;
justify-content: center;
.title {
position: absolute;
bottom: 0;
width: 358px;
height: 26.83vh;
.name {
position: absolute;
bottom: 2vh;
width: 100%;
font-family: $font-special;
font-size: 4vh;
line-height: 6.67vh;
text-align: center;
@include single_ellipsis;
&.small {
font-size: 2vh;
}
}
}
img {
width: 180px;
height: 15vh;
margin-top: 0;
z-index: 1;
}
}
}
&.bigIcon {
.item {
background: v-bind(app_bg);
img {
width: 200px;
height: 16.67vh;
margin-top: 0;
}
}
}
}
}
}
.open-course-div {
text-align: right;
position: absolute;
right: 20px;
top: 1.67vh;
button {
background: #89f57b;
border-color: #89f57b;
color: #000;
font-weight: bold;
}
}
</style>