Files
qncV4uni-app/src/pages/toolbox/category.vue
2026-05-16 15:47:07 +08:00

206 lines
4.2 KiB
Vue

<script setup lang="ts">
import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { toolboxCategories, getCategoryAllTools } from '@/config/toolboxRegistry'
definePage({
style: {
navigationBarTitleText: '分类工具',
navigationStyle: 'default',
navigationBarBackgroundColor: '#ffffff',
navigationBarTextStyle: 'black',
},
})
const categoryKey = ref('')
const category = ref<any>(null)
const tools = ref<any[]>([])
onLoad((query) => {
const key = (query?.category as string) || ''
categoryKey.value = key
const cat = toolboxCategories.find(c => c.key === key)
if (cat) {
category.value = cat
tools.value = getCategoryAllTools(key)
uni.setNavigationBarTitle({ title: cat.name })
}
})
function goTool(key: string) {
uni.navigateTo({
url: `/pages/toolbox/query?key=${encodeURIComponent(key)}`,
})
}
</script>
<template>
<view class="page-root">
<scroll-view scroll-y class="scrollarea">
<view class="page">
<view v-if="category" class="cat-header">
<view class="cat-icon-large" :style="{ background: `${category.color}15` }">
<view :class="['icon', category.icon]" :style="{ color: category.color }" />
</view>
<view class="cat-info">
<text class="cat-name">{{ category.name }}</text>
<text class="cat-count"> {{ tools.length }} 个工具</text>
</view>
</view>
<view class="tool-list">
<view
v-for="item in tools"
:key="item.key"
class="tool-item"
@tap="goTool(item.key)"
>
<view class="item-icon-wrap" :style="{ background: category ? `${category.color}12` : '#e8f0fe' }">
<view :class="['item-icon', item.icon]" :style="{ color: category?.color || '#1768ff' }" />
</view>
<view class="item-content">
<text class="item-name">{{ item.name }}</text>
<text class="item-desc">{{ item.desc }}</text>
</view>
<!-- <text class="item-arrow"></text> -->
</view>
</view>
</view>
</scroll-view>
</view>
</template>
<style scoped lang="scss">
.page-root {
height: 100vh;
display: flex;
flex-direction: column;
background: linear-gradient(180deg, #f8faff 0%, #f3f5fb 100%);
}
.scrollarea {
flex: 1;
min-height: 0;
height: 0;
}
.page {
padding: 24rpx 24rpx 40rpx;
box-sizing: border-box;
}
.cat-header {
display: flex;
align-items: center;
gap: 24rpx;
padding: 28rpx 32rpx;
background: linear-gradient(145deg, #ffffff 0%, #f7f8ff 100%);
border-radius: 24rpx;
border: 1rpx solid #e5e6f0;
margin-bottom: 24rpx;
box-shadow:
0 16rpx 40rpx rgba(15, 35, 52, 0.04),
0 0 0 1rpx rgba(255, 255, 255, 0.5) inset;
}
.cat-icon-large {
width: 88rpx;
height: 88rpx;
border-radius: 24rpx;
display: flex;
align-items: center;
justify-content: center;
}
.icon {
font-size: 44rpx;
}
.cat-info {
flex: 1;
}
.cat-name {
display: block;
font-size: 32rpx;
font-weight: 600;
color: #1d2129;
margin-bottom: 6rpx;
}
.cat-count {
display: block;
font-size: 24rpx;
color: #86909c;
}
.tool-list {
background: linear-gradient(145deg, #ffffff 0%, #f7f8ff 100%);
border-radius: 24rpx;
border: 1rpx solid #e5e6f0;
overflow: hidden;
box-shadow:
0 16rpx 40rpx rgba(15, 35, 52, 0.04),
0 0 0 1rpx rgba(255, 255, 255, 0.5) inset;
}
.tool-item {
display: flex;
align-items: center;
gap: 20rpx;
padding: 24rpx 28rpx;
border-bottom: 1rpx solid #f2f3f5;
}
.tool-item:last-child {
border-bottom: none;
}
.tool-item:active {
background: #f7f8fa;
}
.item-icon-wrap {
width: 72rpx;
height: 72rpx;
border-radius: 18rpx;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.item-icon {
font-size: 34rpx;
}
.item-content {
flex: 1;
min-width: 0;
}
.item-name {
display: block;
font-size: 28rpx;
font-weight: 500;
color: #1d2129;
margin-bottom: 4rpx;
}
.item-desc {
display: block;
font-size: 22rpx;
color: #86909c;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.item-arrow {
font-size: 24rpx;
color: #c9cdd4;
flex-shrink: 0;
}
</style>