pda-uni-app-perkins/pages/home/index.vue

341 lines
6.8 KiB
Vue
Raw Normal View History

<template>
2025-10-31 22:49:51 +08:00
<view class="container">
<view class="header">
<view class="header-bg">
<view class="wave w1" />
<view class="wave w2" />
</view>
<button class="icon-btn" @click="toggleDrawer">
<i class="icon icon-menu" style="font-size:40rpx;color:#fff"></i>
</button>
<text class="header-title">WMS移动终端模板</text>
<button class="icon-btn" @click="noop">
<i class="icon icon-notifications" style="font-size:40rpx;color:#fff"></i>
</button>
</view>
<!-- Drawer Overlay -->
<view class="drawer-mask" :class="{ show: showDrawer }" @click="closeDrawer" />
<view class="drawer" :class="{ open: showDrawer }">
<view class="drawer-top">
<text class="drawer-title">导航</text>
</view>
<view class="drawer-list">
<button
v-for="item in drawerItems"
:key="item.path"
class="drawer-link"
@click="nav(item.path)"
>
<i class="icon" :class="item.icon"></i>
<text class="drawer-text">{{ item.label }}</text>
</button>
</view>
</view>
<view class="content">
<view class="grid">
<view
v-for="(item, index) in quickLinks"
:key="item.path"
class="card"
:class="{ single: quickLinks.length % 2 === 1 && index === quickLinks.length - 1 }"
@click="go(item.path)"
>
<view class="action-icon">
<i class="icon" :class="item.icon" style="font-size:48rpx;color:#fff"></i>
</view>
<text class="action-title">{{ item.label }}</text>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
chartSize: 260,
showDrawer: false,
quickLinks: [
{ label: '测试页面', path: '/pages/test/index', icon: 'icon-menu' },
{ label: '空载具入库', path: '/pages/stock-in/empty', icon: 'icon-local_shipping' },
{ label: '发动机入库', path: '/pages/stock-in/engine', icon: 'icon-save' },
{ label: '原材料入库', path: '/pages/stock-in/raw', icon: 'icon-inventory' },
// { label: '通道三原材料回库', path: '/pages/stock-in/raw-return', icon: 'icon-task_alt' }
2025-10-31 22:49:51 +08:00
]
}
},
computed: {
drawerItems() {
return this.quickLinks
}
},
methods: {
noop() { },
toggleDrawer() { this.showDrawer = !this.showDrawer },
closeDrawer() { this.showDrawer = false },
nav(url) { this.showDrawer = false; this.go(url) },
go(url) {
uni.navigateTo({
url
})
},
arcPath(startRatio, endRatio) {
const start = this.polar(50, 50, 40, startRatio * 2 * Math.PI)
const end = this.polar(50, 50, 40, endRatio * 2 * Math.PI)
const large = endRatio - startRatio > 0.5 ? 1 : 0
return `M 50 50 L ${start.x} ${start.y} A 40 40 0 ${large} 1 ${end.x} ${end.y} Z`
},
polar(cx, cy, r, ang) {
return {
x: cx + r * Math.cos(ang),
y: cy + r * Math.sin(ang)
}
}
}
}
</script>
<style scoped>
.container {
min-height: 100vh;
background: var(--bg-gray);
}
.header {
height: 200rpx;
position: relative;
padding: 24rpx;
display: flex;
align-items: center;
justify-content: space-between;
}
.header-bg {
position: absolute;
inset: 0;
background: linear-gradient(180deg, var(--grad-primary-start), var(--grad-primary-mid));
}
.wave {
position: absolute;
left: 0;
right: 0;
height: 120rpx;
background: radial-gradient(ellipse at 50% 30%, rgba(255, 255, 255, .25), rgba(255, 255, 255, 0) 60%);
opacity: .6;
}
.w1 {
top: 10rpx
}
.w2 {
top: 80rpx
}
.icon-btn {
z-index: 1;
width: 64rpx;
height: 64rpx;
border-radius: 32rpx;
background: transparent;
border: none;
display: flex;
align-items: center;
justify-content: center;
}
.header-title {
z-index: 1;
color: #fff;
font-size: 34rpx;
font-weight: 600;
}
.content {
padding: 24rpx;
}
.grid {
display: grid;
grid-template-columns: 1fr 1fr;
grid-gap: 24rpx;
}
.card {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 180rpx;
border-radius: 20rpx;
background: linear-gradient(90deg, var(--grad-contrast-start), var(--grad-contrast-end));
box-shadow: 0 8rpx 22rpx rgba(5, 220, 239, .25);
}
.card.single {
grid-column: span 2;
height: 180rpx;
}
.action-icon {
width: 96rpx;
height: 96rpx;
border-radius: 48rpx;
display: flex;
align-items: center;
justify-content: center;
background: rgba(255, 255, 255, .25);
margin-bottom: 12rpx;
}
.action-icon .icon {
color: #fff;
font-size: 48rpx
}
.action-title {
color: #fff;
font-size: 28rpx;
}
.section {
margin-top: 24rpx;
border-radius: 16rpx;
padding: 24rpx;
background: #fff;
}
.section-title {
color: var(--text-color);
font-size: 32rpx;
font-weight: 600;
margin-bottom: 16rpx;
}
.chart-row {
display: flex;
align-items: center;
}
.legend {
margin-left: 24rpx;
}
.legend-item {
display: flex;
align-items: center;
margin-bottom: 24rpx;
}
.dot {
width: 20rpx;
height: 20rpx;
border-radius: 10rpx;
margin-right: 12rpx;
}
.legend-text {
color: var(--text-light);
font-size: 28rpx;
}
.pie {
width: 280rpx;
height: 280rpx;
border-radius: 50%;
background: conic-gradient(#7FFFAA 0 60%, #00FFFF 60% 100%);
box-shadow: inset 0 0 0 0 #fff;
}
.drawer-mask {
position: fixed;
left: 0;
top: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, .28);
opacity: 0;
pointer-events: none;
transition: opacity .22s ease;
z-index: 998;
}
.drawer-mask.show {
opacity: 1;
pointer-events: auto;
}
.drawer {
position: fixed;
left: 0;
top: 0;
bottom: 0;
width: 460rpx;
background: linear-gradient(180deg, #05DCEF 0%, #7DE2F5 60%, #FFFFFF 100%);
box-shadow: 16rpx 0 32rpx rgba(0, 0, 0, .15);
transform: translateX(-104%);
transition: transform .26s cubic-bezier(.2, .8, .2, 1);
z-index: 999;
border-top-right-radius: 24rpx;
border-bottom-right-radius: 24rpx;
overflow: hidden;
display: flex;
flex-direction: column;
}
.drawer.open {
transform: translateX(0);
}
.drawer-top {
padding: calc(env(safe-area-inset-top, 0) + 24rpx) 16rpx 8rpx 24rpx;
}
.drawer-title {
color: #fff;
font-size: 44rpx;
font-weight: 800;
letter-spacing: 1rpx;
}
.drawer-list {
flex: 1;
overflow: auto;
padding: 8rpx 0 24rpx 0;
display: flex;
flex-direction: column;
}
.drawer-link {
width: 100%;
height: 110rpx;
border: none;
border-radius: 0;
background: transparent;
display: flex;
align-items: center;
justify-content: flex-start;
padding: 0 24rpx;
}
.drawer-link:active {
background: rgba(255, 255, 255, .12);
}
.drawer-link .icon {
color: #ffffff;
font-size: 38rpx;
margin-right: 16rpx;
}
.drawer-text {
color: #fff;
font-size: 34rpx;
font-weight: 600;
}
</style>