chore: 初始化前端仓库并迁移 admin-ui

- 创建 rui-frontend 前端仓库
- 迁移 admin-ui 管理后台
- 创建 cashier-mobile 和 customer-mobile 占位项目
- 配置 pnpm workspace
This commit is contained in:
2026-06-04 05:14:11 +08:00
commit 82a19101a8
153 changed files with 21561 additions and 0 deletions
@@ -0,0 +1,53 @@
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const stats = [
{ key: 'users', label: '', value: 1280, growth: '+12%', icon: 'UserFilled', color: '#1677ff' },
{ key: 'today', label: '', value: 23, growth: '+8%', icon: 'TrendCharts', color: '#52c41a' },
{ key: 'active', label: '', value: 856, growth: '+23%', icon: 'DataLine', color: '#722ed1' },
{ key: 'orders', label: '', value: 5680, growth: '+15%', icon: 'ShoppingCart', color: '#fa8c16' },
].map(s => ({ ...s, label: t(`dashboard.${s.key}`) }))
const recent = [
{ name: '张三', actionKey: 'register', time: '10m' },
{ name: '李四', actionKey: 'login', time: '30m' },
{ name: '王五', actionKey: 'order', time: '1h' },
{ name: '赵六', actionKey: 'comment', time: '2h' },
].map(r => ({ ...r, action: t(`dashboard.action.${r.actionKey}`) }))
</script>
<template>
<div>
<h2 class="text-xl font-bold mb-5">{{ t('dashboard.title') }}</h2>
<div class="grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-4 gap-4 mb-5">
<div v-for="s in stats" :key="s.key" class="stat-card">
<div class="flex items-start justify-between">
<div>
<p class="text-sm text-gray-500 mb-1">{{ s.label }}</p>
<p class="text-3xl font-bold mb-1">{{ s.value.toLocaleString() }}</p>
<span class="text-xs" :style="{ color: s.color }">{{ s.growth }} {{ t('dashboard.vsLastWeek') }}</span>
</div>
<div class="stat-icon" :style="{ background: s.color + '15', color: s.color }">
<el-icon :size="24"><component :is="s.icon" /></el-icon>
</div>
</div>
</div>
</div>
<h3 class="text-lg font-bold mb-4">{{ t('dashboard.recent') }}</h3>
<div class="stat-card">
<el-timeline>
<el-timeline-item v-for="(r, i) in recent" :key="i" :timestamp="r.time" placement="top">
<span class="font-medium">{{ r.name }}</span>
<span class="text-gray-500 ml-2">{{ r.action }}</span>
</el-timeline-item>
</el-timeline>
</div>
</div>
</template>
<style scoped>
.stat-card { background: var(--el-bg-color-overlay); border-radius: 8px; padding: 20px; box-shadow: 0 1px 3px rgba(0,0,0,0.04); transition: box-shadow 0.2s; }
.stat-card:hover { box-shadow: 0 4px 12px rgba(0,0,0,0.08); }
.stat-icon { width: 48px; height: 48px; border-radius: 12px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
</style>