第 0 阶段:项目初始化
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import { RouterView } from 'vue-router'
|
||||
|
||||
import AppLayout from './layouts/AppLayout.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AppLayout>
|
||||
<RouterView />
|
||||
</AppLayout>
|
||||
</template>
|
||||
@@ -0,0 +1,6 @@
|
||||
import axios from 'axios'
|
||||
|
||||
export const apiClient = axios.create({
|
||||
baseURL: '/api',
|
||||
timeout: 10000,
|
||||
})
|
||||
@@ -0,0 +1,32 @@
|
||||
<script setup lang="ts">
|
||||
import { Bell, House, Shop, Tickets, UserFilled, Wallet } from '@element-plus/icons-vue'
|
||||
|
||||
const navItems = [
|
||||
{ label: '首页', to: '/', icon: House },
|
||||
{ label: '租号', to: '/listings', icon: Shop },
|
||||
{ label: '订单', to: '/orders', icon: Tickets },
|
||||
{ label: '钱包', to: '/wallet', icon: Wallet },
|
||||
{ label: '通知', to: '/notifications', icon: Bell },
|
||||
{ label: '实名', to: '/realname', icon: UserFilled },
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="app-shell">
|
||||
<aside class="sidebar">
|
||||
<RouterLink class="brand" to="/">
|
||||
<span class="brand-mark">H</span>
|
||||
<span>哈夫币租号</span>
|
||||
</RouterLink>
|
||||
<nav class="nav">
|
||||
<RouterLink v-for="item in navItems" :key="item.to" class="nav-link" :to="item.to">
|
||||
<el-icon><component :is="item.icon" /></el-icon>
|
||||
<span>{{ item.label }}</span>
|
||||
</RouterLink>
|
||||
</nav>
|
||||
</aside>
|
||||
<main class="main">
|
||||
<slot />
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,11 @@
|
||||
import 'element-plus/dist/index.css'
|
||||
import './styles/base.css'
|
||||
|
||||
import ElementPlus from 'element-plus'
|
||||
import { createPinia } from 'pinia'
|
||||
import { createApp } from 'vue'
|
||||
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
|
||||
createApp(App).use(createPinia()).use(router).use(ElementPlus).mount('#app')
|
||||
@@ -0,0 +1,24 @@
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes: [
|
||||
{ path: '/', name: 'home', component: () => import('@/views/public/HomeView.vue') },
|
||||
{ path: '/listings', name: 'listings', component: () => import('@/views/public/ListingsView.vue') },
|
||||
{ path: '/listings/:id', name: 'listing-detail', component: () => import('@/views/public/ListingDetailView.vue') },
|
||||
{ path: '/orders/create', name: 'order-create', component: () => import('@/views/account/OrderCreateView.vue') },
|
||||
{ path: '/orders', name: 'orders', component: () => import('@/views/account/OrdersView.vue') },
|
||||
{ path: '/orders/:id', name: 'order-detail', component: () => import('@/views/account/OrderDetailView.vue') },
|
||||
{ path: '/wallet', name: 'wallet', component: () => import('@/views/account/WalletView.vue') },
|
||||
{ path: '/notifications', name: 'notifications', component: () => import('@/views/account/NotificationsView.vue') },
|
||||
{ path: '/realname', name: 'realname', component: () => import('@/views/account/RealnameView.vue') },
|
||||
{ path: '/seller/listings', name: 'seller-listings', component: () => import('@/views/seller/SellerListingsView.vue') },
|
||||
{ path: '/seller/handoffs', name: 'seller-handoffs', component: () => import('@/views/seller/SellerHandoffsView.vue') },
|
||||
{ path: '/seller/earnings', name: 'seller-earnings', component: () => import('@/views/seller/SellerEarningsView.vue') },
|
||||
{ path: '/admin/dashboard', name: 'admin-dashboard', component: () => import('@/views/admin/AdminDashboardView.vue') },
|
||||
{ path: '/admin/disputes', name: 'admin-disputes', component: () => import('@/views/admin/AdminDisputesView.vue') },
|
||||
{ path: '/admin/system-configs', name: 'admin-system-configs', component: () => import('@/views/admin/AdminSystemConfigsView.vue') },
|
||||
],
|
||||
})
|
||||
|
||||
export default router
|
||||
@@ -0,0 +1,9 @@
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
export const useSessionStore = defineStore('session', {
|
||||
state: () => ({
|
||||
token: '',
|
||||
phone: '',
|
||||
realnameStatus: 'unknown',
|
||||
}),
|
||||
})
|
||||
@@ -0,0 +1,164 @@
|
||||
:root {
|
||||
color: #1f2933;
|
||||
background: #f6f8fb;
|
||||
font-family:
|
||||
Inter, "PingFang SC", "Microsoft YaHei", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
|
||||
sans-serif;
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
min-width: 320px;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.app-shell {
|
||||
display: grid;
|
||||
min-height: 100vh;
|
||||
grid-template-columns: 248px 1fr;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
border-right: 1px solid #e4e7ed;
|
||||
background: #ffffff;
|
||||
padding: 20px 16px;
|
||||
}
|
||||
|
||||
.brand {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
min-height: 44px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.brand-mark {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 8px;
|
||||
background: #0f766e;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.nav {
|
||||
display: grid;
|
||||
gap: 6px;
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
min-height: 40px;
|
||||
border-radius: 8px;
|
||||
padding: 0 12px;
|
||||
color: #52616f;
|
||||
}
|
||||
|
||||
.nav-link.router-link-active {
|
||||
background: #e8f5f2;
|
||||
color: #0f766e;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.main {
|
||||
min-width: 0;
|
||||
padding: 32px;
|
||||
}
|
||||
|
||||
.page {
|
||||
max-width: 1120px;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
max-width: 720px;
|
||||
}
|
||||
|
||||
.eyebrow {
|
||||
margin: 0 0 8px;
|
||||
color: #0f766e;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0;
|
||||
font-size: 32px;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.page-header p:last-child {
|
||||
margin: 12px 0 0;
|
||||
color: #52616f;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.metric-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: 16px;
|
||||
margin-top: 28px;
|
||||
}
|
||||
|
||||
.metric-card {
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 8px;
|
||||
background: #ffffff;
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
.metric-card span {
|
||||
display: block;
|
||||
color: #6b7785;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.metric-card strong {
|
||||
display: block;
|
||||
margin-top: 8px;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
@media (max-width: 760px) {
|
||||
.app-shell {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 10;
|
||||
border-right: 0;
|
||||
border-bottom: 1px solid #e4e7ed;
|
||||
}
|
||||
|
||||
.nav {
|
||||
grid-auto-flow: column;
|
||||
grid-auto-columns: max-content;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.main {
|
||||
padding: 24px 16px;
|
||||
}
|
||||
|
||||
.metric-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<section class="page">
|
||||
<div class="page-header">
|
||||
<p class="eyebrow">Notifications</p>
|
||||
<h1>站内信</h1>
|
||||
<p>接收审核、交接、归还、申诉和仲裁结果通知。</p>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
@@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<section class="page">
|
||||
<div class="page-header">
|
||||
<p class="eyebrow">Create Order</p>
|
||||
<h1>创建订单</h1>
|
||||
<p>确认租期、租金、押金和账号资产快照。</p>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
@@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<section class="page">
|
||||
<div class="page-header">
|
||||
<p class="eyebrow">Order Timeline</p>
|
||||
<h1>订单详情</h1>
|
||||
<p>展示状态机时间线、交接记录、归还入口和申诉入口。</p>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
@@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<section class="page">
|
||||
<div class="page-header">
|
||||
<p class="eyebrow">Orders</p>
|
||||
<h1>我的订单</h1>
|
||||
<p>跟踪待交接、租赁中、待归还、申诉中和已完成订单。</p>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
@@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<section class="page">
|
||||
<div class="page-header">
|
||||
<p class="eyebrow">Realname</p>
|
||||
<h1>实名认证</h1>
|
||||
<p>号主发布前必须完成实名认证。</p>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
@@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<section class="page">
|
||||
<div class="page-header">
|
||||
<p class="eyebrow">Wallet</p>
|
||||
<h1>钱包</h1>
|
||||
<p>查看可用余额、冻结余额和不可变资金流水。</p>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
@@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<section class="page">
|
||||
<div class="page-header">
|
||||
<p class="eyebrow">Admin</p>
|
||||
<h1>后台仪表盘</h1>
|
||||
<p>待审核、待仲裁、订单和流水概览。</p>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
@@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<section class="page">
|
||||
<div class="page-header">
|
||||
<p class="eyebrow">Arbitration</p>
|
||||
<h1>仲裁中心</h1>
|
||||
<p>处理无法登录、资产损失、哈夫币争议和超时归还。</p>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
@@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<section class="page">
|
||||
<div class="page-header">
|
||||
<p class="eyebrow">Configs</p>
|
||||
<h1>系统配置</h1>
|
||||
<p>管理交接超时、归还超时、短信限流、最低押金和抽成比例。</p>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
@@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<section class="page">
|
||||
<div class="page-header">
|
||||
<p class="eyebrow">Delta Force Rental</p>
|
||||
<h1>哈夫币租号平台</h1>
|
||||
<p>先把账号发布、交接、订单、押金和仲裁链路打牢,再接真实支付和更复杂的风控。</p>
|
||||
</div>
|
||||
<div class="metric-grid">
|
||||
<div class="metric-card">
|
||||
<span>一期路线</span>
|
||||
<strong>自研业务核心</strong>
|
||||
</div>
|
||||
<div class="metric-card">
|
||||
<span>交接模式</span>
|
||||
<strong>号主手动交接</strong>
|
||||
</div>
|
||||
<div class="metric-card">
|
||||
<span>资金模型</span>
|
||||
<strong>先做账务</strong>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
@@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<section class="page">
|
||||
<div class="page-header">
|
||||
<p class="eyebrow">Listing Detail</p>
|
||||
<h1>租号详情</h1>
|
||||
<p>展示账号资产、哈夫币快照、租金押金、号主信用和风险提示。</p>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
@@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<section class="page">
|
||||
<div class="page-header">
|
||||
<p class="eyebrow">Listings</p>
|
||||
<h1>租号列表</h1>
|
||||
<p>后续支持区服、平台、价格、押金、段位和哈夫币数量筛选。</p>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
@@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<section class="page">
|
||||
<div class="page-header">
|
||||
<p class="eyebrow">Earnings</p>
|
||||
<h1>收益流水</h1>
|
||||
<p>查看租金、平台抽成、结算和冻结金额。</p>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
@@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<section class="page">
|
||||
<div class="page-header">
|
||||
<p class="eyebrow">Handoffs</p>
|
||||
<h1>交接管理</h1>
|
||||
<p>处理待交接、待归还确认和超时订单。</p>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
@@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<section class="page">
|
||||
<div class="page-header">
|
||||
<p class="eyebrow">Seller</p>
|
||||
<h1>我的发布</h1>
|
||||
<p>管理账号发布、审核状态、上架和下架。</p>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
Reference in New Issue
Block a user