150 lines
4.5 KiB
Vue
150 lines
4.5 KiB
Vue
<template>
|
|
<view class="db-page">
|
|
<view class="db-header" :style="safeAreaStyle">
|
|
<view class="db-header__nav">
|
|
<view class="db-header__left">
|
|
<text class="db-header__back" @click="goWorkbench">←</text>
|
|
<text class="db-header__title">仪表盘</text>
|
|
</view>
|
|
<view /><!-- 胶囊占位 -->
|
|
</view>
|
|
</view>
|
|
|
|
<view class="db-menu-grid">
|
|
<view class="db-menu-item" @click="go(PAGE_PATHS.dbPlansList)">
|
|
<view class="db-menu-icon">📋</view>
|
|
<view class="db-menu-label">计划管理</view>
|
|
</view>
|
|
<view class="db-menu-item" @click="go(PAGE_PATHS.dbInventoryList)">
|
|
<view class="db-menu-icon">📦</view>
|
|
<view class="db-menu-label">出入库管理</view>
|
|
</view>
|
|
<view class="db-menu-item" @click="go(PAGE_PATHS.dbWeighingList)">
|
|
<view class="db-menu-icon">⚖️</view>
|
|
<view class="db-menu-label">地磅单管理</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="db-stat-grid">
|
|
<view class="db-stat-card">
|
|
<view class="db-stat-title">今日入库</view>
|
|
<view class="db-stat-value">
|
|
{{ inboundCount }}<text class="db-stat-suffix">车</text>
|
|
</view>
|
|
</view>
|
|
<view class="db-stat-card">
|
|
<view class="db-stat-title">今日出库</view>
|
|
<view class="db-stat-value">
|
|
{{ outboundCount }}<text class="db-stat-suffix">车</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view v-for="block in chartBlocks" :key="block.title" class="db-chart-block">
|
|
<view class="db-chart-title">{{ block.title }}</view>
|
|
<view v-if="!block.rows.length" class="db-empty" style="padding: 16px">暂无数据</view>
|
|
<view v-for="row in block.rows" :key="row.label" class="db-bar-row">
|
|
<view class="db-bar-label">{{ row.label }}</view>
|
|
<view class="db-bar-track">
|
|
<view class="db-bar-planned" :style="{ width: barPct(row.planned, block.max) }" />
|
|
<view class="db-bar-actual" :style="{ width: barPct(row.actual, block.max) }" />
|
|
</view>
|
|
<view class="db-bar-meta">计划 {{ fmt(row.planned) }} · 实绩 {{ fmt(row.actual) }}</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, computed, onMounted } from 'vue'
|
|
import { onShow } from '@dcloudio/uni-app'
|
|
import { useUserStore } from '@/stores/user'
|
|
import { PAGE_PATHS } from '@/config/api'
|
|
import { dashboardApi } from '@/pages/db/api/db'
|
|
import { getSafeAreaStyle } from '@/utils/safeArea'
|
|
|
|
const safeAreaStyle = getSafeAreaStyle()
|
|
|
|
const userStore = useUserStore()
|
|
const inboundByCargo = ref([])
|
|
const outboundByCargo = ref([])
|
|
const inboundByPartner = ref([])
|
|
const outboundByPartner = ref([])
|
|
|
|
const inboundCount = computed(() => {
|
|
const set = new Set()
|
|
inboundByCargo.value.forEach((i) => {
|
|
if (Number(i.planned) > 0) set.add(i.label)
|
|
})
|
|
return set.size
|
|
})
|
|
|
|
const outboundCount = computed(() => {
|
|
const set = new Set()
|
|
outboundByCargo.value.forEach((i) => {
|
|
if (Number(i.planned) > 0) set.add(i.label)
|
|
})
|
|
return set.size
|
|
})
|
|
|
|
const chartBlocks = computed(() => [
|
|
pack('今日入库量(按货物,t)', inboundByCargo.value),
|
|
pack('今日出库量(按货物,t)', outboundByCargo.value),
|
|
pack('今日入库量(按往来单位+货物,t)', inboundByPartner.value),
|
|
pack('今日出库量(按往来单位+货物,t)', outboundByPartner.value)
|
|
])
|
|
|
|
function pack(title, rows) {
|
|
const list = Array.isArray(rows) ? rows : []
|
|
const max = Math.max(1, ...list.map((r) => Math.max(Number(r.planned) || 0, Number(r.actual) || 0)))
|
|
return { title, rows: list, max }
|
|
}
|
|
|
|
function barPct(v, max) {
|
|
const n = Number(v) || 0
|
|
return `${Math.min(100, (n / max) * 100)}%`
|
|
}
|
|
|
|
function fmt(v) {
|
|
const n = Number(v)
|
|
return Number.isFinite(n) ? n.toFixed(2) : '0'
|
|
}
|
|
|
|
function goWorkbench() {
|
|
uni.reLaunch({ url: PAGE_PATHS.workbench })
|
|
}
|
|
|
|
function go(url) {
|
|
uni.navigateTo({ url })
|
|
}
|
|
|
|
async function load() {
|
|
try {
|
|
const [a, b, c, d] = await Promise.all([
|
|
dashboardApi.getInboundByCargo(),
|
|
dashboardApi.getOutboundByCargo(),
|
|
dashboardApi.getInboundByPartnerCargo(),
|
|
dashboardApi.getOutboundByPartnerCargo()
|
|
])
|
|
inboundByCargo.value = a || []
|
|
outboundByCargo.value = b || []
|
|
inboundByPartner.value = c || []
|
|
outboundByPartner.value = d || []
|
|
} catch (e) {
|
|
console.error(e)
|
|
}
|
|
}
|
|
|
|
onMounted(load)
|
|
onShow(() => {
|
|
userStore.checkLoginStatus()
|
|
if (!userStore.isLoggedIn) {
|
|
uni.reLaunch({ url: PAGE_PATHS.login })
|
|
}
|
|
})
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
@import '@/styles/db-theme.scss';
|
|
</style>
|