mirror of
https://gitee.com/blackfox/geekai.git
synced 2025-12-08 09:48:25 +08:00
调整移动端App列表样式
This commit is contained in:
parent
79522d9ab5
commit
4641482865
@ -321,6 +321,11 @@ const routes = [
|
|||||||
name: 'mobile-chat-export',
|
name: 'mobile-chat-export',
|
||||||
component: () => import('@/views/mobile/ChatExport.vue'),
|
component: () => import('@/views/mobile/ChatExport.vue'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/mobile/apps',
|
||||||
|
name: 'mobile-apps',
|
||||||
|
component: () => import('@/views/mobile/Apps.vue'),
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
268
web/src/views/mobile/Apps.vue
Normal file
268
web/src/views/mobile/Apps.vue
Normal file
@ -0,0 +1,268 @@
|
|||||||
|
<template>
|
||||||
|
<div class="apps-page">
|
||||||
|
<van-nav-bar title="全部应用" left-arrow @click-left="router.back()" />
|
||||||
|
|
||||||
|
<div class="apps-filter mb-8 pt-8" style="border: 1px solid #ccc">
|
||||||
|
<van-tabs v-model="activeTab" animated swipeable>
|
||||||
|
<van-tab title="全部分类">
|
||||||
|
<div class="app-list">
|
||||||
|
<van-list v-model="loading" :finished="true" finished-text="" @load="fetchApps()">
|
||||||
|
<van-cell v-for="item in apps" :key="item.id" class="app-cell">
|
||||||
|
<div class="app-card">
|
||||||
|
<div class="app-info">
|
||||||
|
<div class="app-image">
|
||||||
|
<van-image :src="item.icon" round />
|
||||||
|
</div>
|
||||||
|
<div class="app-detail">
|
||||||
|
<div class="app-title">{{ item.name }}</div>
|
||||||
|
<div class="app-desc">{{ item.hello_msg }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="app-actions">
|
||||||
|
<van-button
|
||||||
|
size="small"
|
||||||
|
type="primary"
|
||||||
|
class="action-btn"
|
||||||
|
@click="useRole(item.id)"
|
||||||
|
>对话</van-button
|
||||||
|
>
|
||||||
|
<van-button
|
||||||
|
size="small"
|
||||||
|
:type="hasRole(item.key) ? 'danger' : 'success'"
|
||||||
|
class="action-btn"
|
||||||
|
@click="updateRole(item, hasRole(item.key) ? 'remove' : 'add')"
|
||||||
|
>
|
||||||
|
{{ hasRole(item.key) ? '移除' : '添加' }}
|
||||||
|
</van-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</van-cell>
|
||||||
|
</van-list>
|
||||||
|
</div>
|
||||||
|
</van-tab>
|
||||||
|
<van-tab v-for="type in appTypes" :key="type.id" :title="type.name">
|
||||||
|
<div class="app-list">
|
||||||
|
<van-list
|
||||||
|
v-model="loading"
|
||||||
|
:finished="true"
|
||||||
|
finished-text=""
|
||||||
|
@load="fetchApps(type.id)"
|
||||||
|
>
|
||||||
|
<van-cell v-for="item in typeApps" :key="item.id" class="app-cell">
|
||||||
|
<div class="app-card">
|
||||||
|
<div class="app-info">
|
||||||
|
<div class="app-image">
|
||||||
|
<van-image :src="item.icon" round />
|
||||||
|
</div>
|
||||||
|
<div class="app-detail">
|
||||||
|
<div class="app-title">{{ item.name }}</div>
|
||||||
|
<div class="app-desc">{{ item.hello_msg }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="app-actions">
|
||||||
|
<van-button
|
||||||
|
size="small"
|
||||||
|
type="primary"
|
||||||
|
class="action-btn"
|
||||||
|
@click="useRole(item.id)"
|
||||||
|
>对话</van-button
|
||||||
|
>
|
||||||
|
<van-button
|
||||||
|
size="small"
|
||||||
|
:type="hasRole(item.key) ? 'danger' : 'success'"
|
||||||
|
class="action-btn"
|
||||||
|
@click="updateRole(item, hasRole(item.key) ? 'remove' : 'add')"
|
||||||
|
>
|
||||||
|
{{ hasRole(item.key) ? '移除' : '添加' }}
|
||||||
|
</van-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</van-cell>
|
||||||
|
</van-list>
|
||||||
|
</div>
|
||||||
|
</van-tab>
|
||||||
|
</van-tabs>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { checkSession } from '@/store/cache'
|
||||||
|
import { httpGet, httpPost } from '@/utils/http'
|
||||||
|
import { arrayContains, removeArrayItem, showLoginDialog, substr } from '@/utils/libs'
|
||||||
|
import { showNotify } from 'vant'
|
||||||
|
import { onMounted, ref } from 'vue'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
const isLogin = ref(false)
|
||||||
|
const apps = ref([])
|
||||||
|
const typeApps = ref([])
|
||||||
|
const appTypes = ref([])
|
||||||
|
const loading = ref(false)
|
||||||
|
const roles = ref([])
|
||||||
|
const activeTab = ref(0)
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
checkSession()
|
||||||
|
.then((user) => {
|
||||||
|
isLogin.value = true
|
||||||
|
roles.value = user.chat_roles
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
|
fetchAppTypes()
|
||||||
|
fetchApps()
|
||||||
|
})
|
||||||
|
|
||||||
|
const fetchAppTypes = () => {
|
||||||
|
httpGet('/api/app/type/list')
|
||||||
|
.then((res) => {
|
||||||
|
appTypes.value = res.data
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
showNotify({ type: 'danger', message: '获取应用分类失败:' + e.message })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchApps = (typeId = '') => {
|
||||||
|
httpGet('/api/app/list', { tid: typeId })
|
||||||
|
.then((res) => {
|
||||||
|
const items = res.data
|
||||||
|
// 处理 hello message
|
||||||
|
for (let i = 0; i < items.length; i++) {
|
||||||
|
items[i].intro = substr(items[i].hello_msg, 80)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeId) {
|
||||||
|
typeApps.value = items
|
||||||
|
} else {
|
||||||
|
apps.value = items
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
showNotify({ type: 'danger', message: '获取应用失败:' + e.message })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateRole = (row, opt) => {
|
||||||
|
if (!isLogin.value) {
|
||||||
|
return showLoginDialog(router)
|
||||||
|
}
|
||||||
|
|
||||||
|
const title = ref('')
|
||||||
|
if (opt === 'add') {
|
||||||
|
title.value = '添加应用'
|
||||||
|
const exists = arrayContains(roles.value, row.key)
|
||||||
|
if (exists) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
roles.value.push(row.key)
|
||||||
|
} else {
|
||||||
|
title.value = '移除应用'
|
||||||
|
const exists = arrayContains(roles.value, row.key)
|
||||||
|
if (!exists) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
roles.value = removeArrayItem(roles.value, row.key)
|
||||||
|
}
|
||||||
|
httpPost('/api/app/update', { keys: roles.value })
|
||||||
|
.then(() => {
|
||||||
|
showNotify({ type: 'success', message: title.value + '成功!' })
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
showNotify({ type: 'danger', message: title.value + '失败:' + e.message })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasRole = (roleKey) => {
|
||||||
|
return arrayContains(roles.value, roleKey, (v1, v2) => v1 === v2)
|
||||||
|
}
|
||||||
|
|
||||||
|
const useRole = (roleId) => {
|
||||||
|
if (!isLogin.value) {
|
||||||
|
return showLoginDialog(router)
|
||||||
|
}
|
||||||
|
router.push(`/mobile/chat/session?role_id=${roleId}`)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="stylus">
|
||||||
|
.apps-page {
|
||||||
|
min-height 100vh
|
||||||
|
background-color var(--van-background)
|
||||||
|
|
||||||
|
.apps-filter {
|
||||||
|
padding 10px 0
|
||||||
|
|
||||||
|
:deep(.van-tabs__nav) {
|
||||||
|
background var(--van-background-2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-list {
|
||||||
|
padding 0 15px
|
||||||
|
|
||||||
|
.app-cell {
|
||||||
|
padding 0
|
||||||
|
margin-bottom 15px
|
||||||
|
|
||||||
|
.app-card {
|
||||||
|
background var(--van-cell-background)
|
||||||
|
border-radius 12px
|
||||||
|
padding 15px
|
||||||
|
box-shadow 0 2px 12px rgba(0, 0, 0, 0.05)
|
||||||
|
|
||||||
|
.app-info {
|
||||||
|
display flex
|
||||||
|
align-items center
|
||||||
|
margin-bottom 15px
|
||||||
|
|
||||||
|
.app-image {
|
||||||
|
width 60px
|
||||||
|
height 60px
|
||||||
|
margin-right 15px
|
||||||
|
|
||||||
|
:deep(.van-image) {
|
||||||
|
width 100%
|
||||||
|
height 100%
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-detail {
|
||||||
|
flex 1
|
||||||
|
|
||||||
|
.app-title {
|
||||||
|
font-size 16px
|
||||||
|
font-weight 600
|
||||||
|
margin-bottom 5px
|
||||||
|
color var(--van-text-color)
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-desc {
|
||||||
|
font-size 13px
|
||||||
|
color var(--van-gray-6)
|
||||||
|
display -webkit-box
|
||||||
|
-webkit-box-orient vertical
|
||||||
|
-webkit-line-clamp 2
|
||||||
|
overflow hidden
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-actions {
|
||||||
|
display flex
|
||||||
|
gap 10px
|
||||||
|
|
||||||
|
.action-btn {
|
||||||
|
flex 1
|
||||||
|
border-radius 20px
|
||||||
|
padding 0 10px
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -1,60 +1,79 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="index container">
|
<div class="index container">
|
||||||
<h2 class="title">{{ title }}</h2>
|
<div class="header">
|
||||||
<van-notice-bar left-icon="info-o" :scrollable="true">{{ slogan }}}</van-notice-bar>
|
<h2 class="title">{{ title }}</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="content">
|
<div class="content mb-8">
|
||||||
<van-grid :column-num="3" :gutter="10" border>
|
<div class="feature-grid">
|
||||||
<van-grid-item @click="router.push('chat')">
|
<van-grid :column-num="3" :gutter="15" border>
|
||||||
<template #icon>
|
<van-grid-item @click="router.push('chat')" class="feature-item">
|
||||||
<i class="iconfont icon-chat"></i>
|
<template #icon>
|
||||||
</template>
|
<div class="feature-icon">
|
||||||
<template #text>
|
<i class="iconfont icon-chat"></i>
|
||||||
<div class="text">AI 对话</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</van-grid-item>
|
<template #text>
|
||||||
|
<div class="text">AI 对话</div>
|
||||||
|
</template>
|
||||||
|
</van-grid-item>
|
||||||
|
|
||||||
<van-grid-item @click="router.push('image')">
|
<van-grid-item @click="router.push('image')" class="feature-item">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<i class="iconfont icon-mj"></i>
|
<div class="feature-icon">
|
||||||
</template>
|
<i class="iconfont icon-mj"></i>
|
||||||
<template #text>
|
</div>
|
||||||
<div class="text">AI 绘画</div>
|
</template>
|
||||||
</template>
|
<template #text>
|
||||||
</van-grid-item>
|
<div class="text">AI 绘画</div>
|
||||||
|
</template>
|
||||||
|
</van-grid-item>
|
||||||
|
|
||||||
<van-grid-item @click="router.push('imgWall')">
|
<van-grid-item @click="router.push('imgWall')" class="feature-item">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<van-icon name="photo-o" />
|
<div class="feature-icon">
|
||||||
</template>
|
<van-icon name="photo-o" />
|
||||||
<template #text>
|
</div>
|
||||||
<div class="text">AI 画廊</div>
|
</template>
|
||||||
</template>
|
<template #text>
|
||||||
</van-grid-item>
|
<div class="text">AI 画廊</div>
|
||||||
</van-grid>
|
</template>
|
||||||
|
</van-grid-item>
|
||||||
|
</van-grid>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section-header">
|
||||||
|
<h3 class="section-title">推荐应用</h3>
|
||||||
|
<van-button class="more-btn" size="small" icon="arrow" @click="router.push('apps')"
|
||||||
|
>更多</van-button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="app-list">
|
<div class="app-list">
|
||||||
<van-list v-model:loading="loading" :finished="true" finished-text="" @load="fetchApps">
|
<van-list v-model="loading" :finished="true" finished-text="" @load="fetchApps">
|
||||||
<van-cell v-for="item in apps" :key="item.id">
|
<van-cell v-for="item in displayApps" :key="item.id" class="app-cell">
|
||||||
<div>
|
<div class="app-card">
|
||||||
<div class="item">
|
<div class="app-info">
|
||||||
<div class="image flex justify-center items-center">
|
<div class="app-image">
|
||||||
<van-image :src="item.icon" />
|
<van-image :src="item.icon" round />
|
||||||
</div>
|
</div>
|
||||||
<div class="info">
|
<div class="app-detail">
|
||||||
<div class="info-title">{{ item.name }}</div>
|
<div class="app-title">{{ item.name }}</div>
|
||||||
<div class="info-text">{{ item.hello_msg }}</div>
|
<div class="app-desc">{{ item.hello_msg }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="btn">
|
<div class="app-actions">
|
||||||
<div v-if="hasRole(item.key)">
|
<van-button size="small" type="primary" class="action-btn" @click="useRole(item.id)"
|
||||||
<van-button size="small" type="success" @click="useRole(item.id)">使用</van-button>
|
>对话</van-button
|
||||||
<van-button size="small" type="danger" @click="updateRole(item, 'remove')">移除</van-button>
|
>
|
||||||
</div>
|
<van-button
|
||||||
<van-button v-else size="small" style="--el-color-primary: #009999" @click="updateRole(item, 'add')">
|
size="small"
|
||||||
<van-icon name="add-o" />
|
:type="hasRole(item.key) ? 'danger' : 'success'"
|
||||||
<span>添加应用</span>
|
class="action-btn"
|
||||||
|
@click="updateRole(item, hasRole(item.key) ? 'remove' : 'add')"
|
||||||
|
>
|
||||||
|
{{ hasRole(item.key) ? '移除' : '添加' }}
|
||||||
</van-button>
|
</van-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -66,173 +85,245 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted, ref } from "vue";
|
import { checkSession, getSystemInfo } from '@/store/cache'
|
||||||
import { useRouter } from "vue-router";
|
import { httpGet, httpPost } from '@/utils/http'
|
||||||
import { checkSession, getSystemInfo } from "@/store/cache";
|
import { arrayContains, removeArrayItem, showLoginDialog, substr } from '@/utils/libs'
|
||||||
import { httpGet, httpPost } from "@/utils/http";
|
import { ElMessage } from 'element-plus'
|
||||||
import { arrayContains, removeArrayItem, showLoginDialog, substr } from "@/utils/libs";
|
import { showNotify } from 'vant'
|
||||||
import { showNotify } from "vant";
|
import { computed, onMounted, ref } from 'vue'
|
||||||
import { ElMessage } from "element-plus";
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
const title = ref(process.env.VUE_APP_TITLE);
|
const title = ref(process.env.VUE_APP_TITLE)
|
||||||
const router = useRouter();
|
const router = useRouter()
|
||||||
const isLogin = ref(false);
|
const isLogin = ref(false)
|
||||||
const apps = ref([]);
|
const apps = ref([])
|
||||||
const loading = ref(false);
|
const loading = ref(false)
|
||||||
const roles = ref([]);
|
const roles = ref([])
|
||||||
const slogan = ref("你有多大想象力,AI就有多大创造力!");
|
const slogan = ref('你有多大想象力,AI就有多大创造力!')
|
||||||
|
|
||||||
|
// 只显示前5个应用
|
||||||
|
const displayApps = computed(() => {
|
||||||
|
return apps.value.slice(0, 8)
|
||||||
|
})
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getSystemInfo()
|
getSystemInfo()
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
title.value = res.data.title;
|
title.value = res.data.title
|
||||||
if (res.data.slogan) {
|
if (res.data.slogan) {
|
||||||
slogan.value = res.data.slogan;
|
slogan.value = res.data.slogan
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
ElMessage.error("获取系统配置失败:" + e.message);
|
ElMessage.error('获取系统配置失败:' + e.message)
|
||||||
});
|
})
|
||||||
|
|
||||||
checkSession()
|
checkSession()
|
||||||
.then((user) => {
|
.then((user) => {
|
||||||
isLogin.value = true;
|
isLogin.value = true
|
||||||
roles.value = user.chat_roles;
|
roles.value = user.chat_roles
|
||||||
})
|
})
|
||||||
.catch(() => {});
|
.catch(() => {})
|
||||||
fetchApps();
|
fetchApps()
|
||||||
});
|
})
|
||||||
|
|
||||||
const fetchApps = () => {
|
const fetchApps = () => {
|
||||||
httpGet("/api/app/list")
|
httpGet('/api/app/list')
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
const items = res.data;
|
const items = res.data
|
||||||
// 处理 hello message
|
// 处理 hello message
|
||||||
for (let i = 0; i < items.length; i++) {
|
for (let i = 0; i < items.length; i++) {
|
||||||
items[i].intro = substr(items[i].hello_msg, 80);
|
items[i].intro = substr(items[i].hello_msg, 80)
|
||||||
}
|
}
|
||||||
apps.value = items;
|
apps.value = items
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
showNotify({ type: "danger", message: "获取应用失败:" + e.message });
|
showNotify({ type: 'danger', message: '获取应用失败:' + e.message })
|
||||||
});
|
})
|
||||||
};
|
}
|
||||||
|
|
||||||
const updateRole = (row, opt) => {
|
const updateRole = (row, opt) => {
|
||||||
if (!isLogin.value) {
|
if (!isLogin.value) {
|
||||||
return showLoginDialog(router);
|
return showLoginDialog(router)
|
||||||
}
|
}
|
||||||
|
|
||||||
const title = ref("");
|
const title = ref('')
|
||||||
if (opt === "add") {
|
if (opt === 'add') {
|
||||||
title.value = "添加应用";
|
title.value = '添加应用'
|
||||||
const exists = arrayContains(roles.value, row.key);
|
const exists = arrayContains(roles.value, row.key)
|
||||||
if (exists) {
|
if (exists) {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
roles.value.push(row.key);
|
roles.value.push(row.key)
|
||||||
} else {
|
} else {
|
||||||
title.value = "移除应用";
|
title.value = '移除应用'
|
||||||
const exists = arrayContains(roles.value, row.key);
|
const exists = arrayContains(roles.value, row.key)
|
||||||
if (!exists) {
|
if (!exists) {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
roles.value = removeArrayItem(roles.value, row.key);
|
roles.value = removeArrayItem(roles.value, row.key)
|
||||||
}
|
}
|
||||||
httpPost("/api/role/update", { keys: roles.value })
|
httpPost('/api/app/update', { keys: roles.value })
|
||||||
.then(() => {
|
.then(() => {
|
||||||
ElMessage.success({ message: title.value + "成功!", duration: 1000 });
|
ElMessage.success({ message: title.value + '成功!', duration: 1000 })
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
ElMessage.error(title.value + "失败:" + e.message);
|
ElMessage.error(title.value + '失败:' + e.message)
|
||||||
});
|
})
|
||||||
};
|
}
|
||||||
|
|
||||||
const hasRole = (roleKey) => {
|
const hasRole = (roleKey) => {
|
||||||
return arrayContains(roles.value, roleKey, (v1, v2) => v1 === v2);
|
return arrayContains(roles.value, roleKey, (v1, v2) => v1 === v2)
|
||||||
};
|
}
|
||||||
|
|
||||||
const useRole = (roleId) => {
|
const useRole = (roleId) => {
|
||||||
if (!isLogin.value) {
|
if (!isLogin.value) {
|
||||||
return showLoginDialog(router);
|
return showLoginDialog(router)
|
||||||
}
|
}
|
||||||
router.push(`/mobile/chat/session?role_id=${roleId}`);
|
router.push(`/mobile/chat/session?role_id=${roleId}`)
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="stylus">
|
<style scoped lang="stylus">
|
||||||
.index {
|
.index {
|
||||||
color var(--van-text-color)
|
color var(--van-text-color)
|
||||||
.title {
|
background-color var(--van-background)
|
||||||
display flex
|
min-height 100vh
|
||||||
justify-content center
|
display flex
|
||||||
|
flex-direction column
|
||||||
|
|
||||||
|
.header {
|
||||||
|
flex-shrink 0
|
||||||
|
padding 10px 15px
|
||||||
|
text-align center
|
||||||
|
background var(--van-background)
|
||||||
|
position sticky
|
||||||
|
top 0
|
||||||
|
z-index 1
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size 24px
|
||||||
|
font-weight 600
|
||||||
|
color var(--van-text-color)
|
||||||
|
}
|
||||||
|
|
||||||
|
.slogan {
|
||||||
|
font-size 14px
|
||||||
|
color var(--van-gray-6)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
--van-notice-bar-font-size: 16px
|
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
padding 15px 0 60px 0
|
flex 1
|
||||||
.van-grid-item {
|
overflow-y auto
|
||||||
.iconfont {
|
padding 15px
|
||||||
font-size 20px
|
-webkit-overflow-scrolling touch
|
||||||
|
|
||||||
|
.feature-grid {
|
||||||
|
margin-bottom 30px
|
||||||
|
|
||||||
|
.feature-item {
|
||||||
|
padding 15px 0
|
||||||
|
|
||||||
|
.feature-icon {
|
||||||
|
width 50px
|
||||||
|
height 50px
|
||||||
|
border-radius 50%
|
||||||
|
background var(--van-primary-color)
|
||||||
|
display flex
|
||||||
|
align-items center
|
||||||
|
justify-content center
|
||||||
|
margin-bottom 10px
|
||||||
|
|
||||||
|
i, .van-icon {
|
||||||
|
font-size 24px
|
||||||
|
color white
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
font-size 14px
|
||||||
|
font-weight 500
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.text {
|
}
|
||||||
display flex
|
|
||||||
width 100%
|
.section-header {
|
||||||
padding 10px
|
display flex
|
||||||
justify-content center
|
justify-content space-between
|
||||||
font-size 14px
|
align-items center
|
||||||
|
margin-bottom 15px
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size 18px
|
||||||
|
font-weight 600
|
||||||
|
color var(--van-text-color)
|
||||||
|
}
|
||||||
|
|
||||||
|
.more-btn {
|
||||||
|
padding 0 10px
|
||||||
|
font-size 12px
|
||||||
|
border-radius 15px
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-list {
|
.app-list {
|
||||||
padding-top 10px
|
.app-cell {
|
||||||
|
padding 0
|
||||||
|
margin-bottom 15px
|
||||||
|
|
||||||
.item {
|
.app-card {
|
||||||
display flex
|
background var(--van-cell-background)
|
||||||
.image {
|
border-radius 12px
|
||||||
width 80px
|
padding 15px
|
||||||
height 80px
|
box-shadow 0 2px 12px rgba(0, 0, 0, 0.05)
|
||||||
min-width 80px
|
|
||||||
border-radius 5px
|
|
||||||
overflow hidden
|
|
||||||
}
|
|
||||||
|
|
||||||
.info {
|
.app-info {
|
||||||
text-align left
|
display flex
|
||||||
padding 0 10px
|
align-items center
|
||||||
.info-title {
|
margin-bottom 15px
|
||||||
color var(--van-text-color)
|
|
||||||
font-size 1.25rem
|
.app-image {
|
||||||
line-height 1.75rem
|
width 60px
|
||||||
letter-spacing: .025em;
|
height 60px
|
||||||
font-weight: 600;
|
margin-right 15px
|
||||||
word-break: break-all;
|
|
||||||
overflow: hidden;
|
:deep(.van-image) {
|
||||||
display: -webkit-box;
|
width 100%
|
||||||
-webkit-box-orient: vertical;
|
height 100%
|
||||||
-webkit-line-clamp: 1;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-detail {
|
||||||
|
flex 1
|
||||||
|
|
||||||
|
.app-title {
|
||||||
|
font-size 16px
|
||||||
|
font-weight 600
|
||||||
|
margin-bottom 5px
|
||||||
|
color var(--van-text-color)
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-desc {
|
||||||
|
font-size 13px
|
||||||
|
color var(--van-gray-6)
|
||||||
|
display -webkit-box
|
||||||
|
-webkit-box-orient vertical
|
||||||
|
-webkit-line-clamp 2
|
||||||
|
overflow hidden
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.info-text {
|
.app-actions {
|
||||||
padding 5px 0
|
display flex
|
||||||
overflow: hidden;
|
gap 10px
|
||||||
display: -webkit-box;
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
-webkit-line-clamp: 2;
|
|
||||||
word-break: break-all;
|
|
||||||
font-size: .875rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn {
|
.action-btn {
|
||||||
padding 5px 0
|
flex 1
|
||||||
.van-button {
|
border-radius 20px
|
||||||
margin-right 10px
|
padding 0 10px
|
||||||
|
}
|
||||||
.van-icon {
|
|
||||||
margin-right 5px
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user