2026-07-30 17:59:42 +08:00
|
|
|
|
<script setup lang="ts">
|
2026-07-30 21:23:06 +08:00
|
|
|
|
import { computed, onMounted, ref } from 'vue'
|
|
|
|
|
|
import { AlertTriangle, ArrowRight, ClipboardCheck, Clock3, FilePlus2, Users } from '@lucide/vue'
|
2026-07-30 17:59:42 +08:00
|
|
|
|
import { useFirstLegOrdersStore } from '@/stores/firstLegOrders'
|
|
|
|
|
|
import { useTenantAdministrationStore } from '@/stores/tenantAdministration'
|
|
|
|
|
|
import { useAuthStore } from '@/stores/auth'
|
|
|
|
|
|
import { getFirstLegStatusLabel, getFirstLegStatusTone } from '@/utils/firstLegOrder'
|
|
|
|
|
|
|
|
|
|
|
|
const orders = useFirstLegOrdersStore()
|
|
|
|
|
|
const tenant = useTenantAdministrationStore()
|
|
|
|
|
|
const auth = useAuthStore()
|
2026-07-30 21:23:06 +08:00
|
|
|
|
const loading = ref(false)
|
|
|
|
|
|
const loadError = ref('')
|
2026-07-30 17:59:42 +08:00
|
|
|
|
const companyApproved = computed(() => tenant.company.auditStatus === 'ACTIVE')
|
|
|
|
|
|
const stats = computed(() => [
|
|
|
|
|
|
{ label: '进行中订单', value: String(orders.activeCount), icon: Clock3 },
|
|
|
|
|
|
{ label: '待平台审核', value: String(orders.pendingCount), icon: ClipboardCheck },
|
|
|
|
|
|
{ label: '企业成员', value: String(tenant.activeMemberCount), icon: Users },
|
|
|
|
|
|
])
|
|
|
|
|
|
const recentOrders = computed(() => orders.orders.slice(0, 3))
|
2026-07-30 21:23:06 +08:00
|
|
|
|
|
|
|
|
|
|
async function loadDashboardData() {
|
|
|
|
|
|
loading.value = true
|
|
|
|
|
|
loadError.value = ''
|
|
|
|
|
|
const requests: Promise<unknown>[] = []
|
|
|
|
|
|
if (auth.hasPermission('company:profile:view')) requests.push(tenant.loadCompanyContext())
|
|
|
|
|
|
if (auth.hasPermission('company:member:list')) requests.push(tenant.loadMembers())
|
|
|
|
|
|
if (auth.hasPermission('order:first-leg:list')) requests.push(orders.load())
|
|
|
|
|
|
try {
|
|
|
|
|
|
await Promise.all(requests)
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
loadError.value = error instanceof Error ? error.message : '业务总览加载失败'
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
loading.value = false
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
onMounted(() => void loadDashboardData())
|
2026-07-30 17:59:42 +08:00
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<template>
|
2026-07-30 21:23:06 +08:00
|
|
|
|
<div v-loading="loading" class="client-dashboard">
|
|
|
|
|
|
<div v-if="loadError" class="dashboard-load-error" role="alert">
|
|
|
|
|
|
<AlertTriangle :size="20" />
|
|
|
|
|
|
<div><strong>业务总览加载失败</strong><span>{{ loadError }}</span></div>
|
|
|
|
|
|
<el-button :loading="loading" @click="loadDashboardData">重新加载</el-button>
|
|
|
|
|
|
</div>
|
2026-07-30 17:59:42 +08:00
|
|
|
|
<section class="quick-order-band">
|
|
|
|
|
|
<div><span>头程物流</span><h2>{{ auth.hasPermission('order:first-leg:create') ? '创建新的头程订单' : '跟进企业头程订单' }}</h2><p>{{ companyApproved ? '企业资料已审核,可正常提交并跟进订单。' : '企业资料待平台审核,当前可以维护并保存订单草稿。' }}</p></div>
|
|
|
|
|
|
<el-button v-if="auth.hasPermission('order:first-leg:list')" type="primary" size="large" @click="$router.push('/orders/first-leg')"><FilePlus2 :size="18" /> {{ auth.hasPermission('order:first-leg:create') ? '开始下单' : '查看订单' }}</el-button>
|
|
|
|
|
|
</section>
|
|
|
|
|
|
<section class="client-stats">
|
|
|
|
|
|
<article v-for="item in stats" :key="item.label"><component :is="item.icon" :size="20" /><div><span>{{ item.label }}</span><strong>{{ item.value }}</strong></div></article>
|
|
|
|
|
|
</section>
|
|
|
|
|
|
<section class="client-content-grid">
|
|
|
|
|
|
<article class="client-card"><header><div><span class="section-label">ORDERS</span><h3>最近订单</h3></div><el-button text @click="$router.push('/orders/first-leg')">查看全部 <ArrowRight :size="16" /></el-button></header><div v-if="recentOrders.length" class="recent-orders"><button v-for="order in recentOrders" :key="order.id" type="button" @click="$router.push('/orders/first-leg')"><span><strong>{{ order.orderNo || '未提交草稿' }}</strong><small>{{ order.origin }} → {{ order.destination }}</small></span><el-tag :type="getFirstLegStatusTone(order.status)" effect="light">{{ getFirstLegStatusLabel(order.status) }}</el-tag></button></div><div v-else class="client-empty">暂无订单,提交第一笔头程订单后将在这里展示。</div></article>
|
|
|
|
|
|
<article class="client-card"><header><div><span class="section-label">ACCOUNT</span><h3>企业资料</h3></div></header><dl class="profile-summary"><div><dt>企业名称</dt><dd>{{ tenant.company.companyName }}</dd></div><div><dt>审核状态</dt><dd><el-tag :type="companyApproved ? 'success' : 'warning'" effect="light">{{ companyApproved ? '已通过' : '待审核' }}</el-tag></dd></div><div><dt>当前成员</dt><dd>{{ auth.user?.name }}</dd></div></dl><el-button v-if="auth.hasPermission('company:profile:view')" plain @click="$router.push('/company/profile')">{{ companyApproved ? '查看企业资料' : '完善企业资料' }}</el-button></article>
|
|
|
|
|
|
</section>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|