feat: Initialize OneOS asset management app
Sets up the basic structure and configuration for the OneOS asset management and vehicle rental solution. Includes project files, dependencies, and initial UI components.
This commit is contained in:
9
.env.example
Normal file
9
.env.example
Normal file
@@ -0,0 +1,9 @@
|
||||
# GEMINI_API_KEY: Required for Gemini AI API calls.
|
||||
# AI Studio automatically injects this at runtime from user secrets.
|
||||
# Users configure this via the Secrets panel in the AI Studio UI.
|
||||
GEMINI_API_KEY="MY_GEMINI_API_KEY"
|
||||
|
||||
# APP_URL: The URL where this applet is hosted.
|
||||
# AI Studio automatically injects this at runtime with the Cloud Run service URL.
|
||||
# Used for self-referential links, OAuth callbacks, and API endpoints.
|
||||
APP_URL="MY_APP_URL"
|
||||
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
node_modules/
|
||||
build/
|
||||
dist/
|
||||
coverage/
|
||||
.DS_Store
|
||||
*.log
|
||||
.env*
|
||||
!.env.example
|
||||
25
README.md
25
README.md
@@ -1,11 +1,20 @@
|
||||
<div align="center">
|
||||
|
||||
<img width="1200" height="475" alt="GHBanner" src="https://github.com/user-attachments/assets/0aa67016-6eaf-458a-adb2-6e31a0763ed6" />
|
||||
|
||||
<h1>Built with AI Studio</h2>
|
||||
|
||||
<p>The fastest path from prompt to production with Gemini.</p>
|
||||
|
||||
<a href="https://aistudio.google.com/apps">Start building</a>
|
||||
|
||||
</div>
|
||||
|
||||
# Run and deploy your AI Studio app
|
||||
|
||||
This contains everything you need to run your app locally.
|
||||
|
||||
View your app in AI Studio: https://ai.studio/apps/3e4a6e0f-4b62-4281-924e-df064b88b8b5
|
||||
|
||||
## Run Locally
|
||||
|
||||
**Prerequisites:** Node.js
|
||||
|
||||
|
||||
1. Install dependencies:
|
||||
`npm install`
|
||||
2. Set the `GEMINI_API_KEY` in [.env.local](.env.local) to your Gemini API key
|
||||
3. Run the app:
|
||||
`npm run dev`
|
||||
|
||||
13
index.html
Normal file
13
index.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>My Google AI Studio App</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
5
metadata.json
Normal file
5
metadata.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "OneOS 资产管理系统介绍",
|
||||
"description": "基于OneOS平台的企业级资产管理与车辆租赁解决方案对外介绍方案。",
|
||||
"requestFramePermissions": []
|
||||
}
|
||||
4325
package-lock.json
generated
Normal file
4325
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
36
package.json
Normal file
36
package.json
Normal file
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "react-example",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite --port=3000 --host=0.0.0.0",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"clean": "rm -rf dist",
|
||||
"lint": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@google/genai": "^1.29.0",
|
||||
"@tailwindcss/vite": "^4.1.14",
|
||||
"@vitejs/plugin-react": "^5.0.4",
|
||||
"clsx": "^2.1.1",
|
||||
"dotenv": "^17.2.3",
|
||||
"express": "^4.21.2",
|
||||
"lucide-react": "^0.546.0",
|
||||
"motion": "^12.23.24",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"tailwind-merge": "^3.5.0",
|
||||
"vite": "^6.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/node": "^22.14.0",
|
||||
"autoprefixer": "^10.4.21",
|
||||
"tailwindcss": "^4.1.14",
|
||||
"tsx": "^4.21.0",
|
||||
"typescript": "~5.8.2",
|
||||
"vite": "^6.2.0"
|
||||
}
|
||||
}
|
||||
581
src/App.tsx
Normal file
581
src/App.tsx
Normal file
@@ -0,0 +1,581 @@
|
||||
/**
|
||||
* @license
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import {
|
||||
ShieldCheck,
|
||||
LayoutDashboard,
|
||||
Smartphone,
|
||||
BarChart3,
|
||||
Settings,
|
||||
FileText,
|
||||
Truck,
|
||||
ClipboardCheck,
|
||||
AlertCircle,
|
||||
Database,
|
||||
ChevronRight,
|
||||
Menu,
|
||||
X,
|
||||
ArrowRight,
|
||||
CheckCircle2,
|
||||
Zap
|
||||
} from 'lucide-react';
|
||||
import { motion, AnimatePresence } from 'motion/react';
|
||||
import { clsx, type ClassValue } from 'clsx';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs));
|
||||
}
|
||||
|
||||
// --- Components ---
|
||||
|
||||
const Navbar = ({ activeTab, setActiveTab }: { activeTab: string, setActiveTab: (tab: string) => void }) => {
|
||||
const [isScrolled, setIsScrolled] = useState(false);
|
||||
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const handleScroll = () => setIsScrolled(window.scrollY > 20);
|
||||
window.addEventListener('scroll', handleScroll);
|
||||
return () => window.removeEventListener('scroll', handleScroll);
|
||||
}, []);
|
||||
|
||||
const tabs = [
|
||||
{ id: 'asset', label: '资产管理系统' },
|
||||
{ id: 'rental', label: '车辆租赁系统' },
|
||||
];
|
||||
|
||||
return (
|
||||
<nav className={cn(
|
||||
"fixed top-0 left-0 right-0 z-50 transition-all duration-300 border-b",
|
||||
isScrolled ? "bg-white/80 backdrop-blur-md py-3 border-slate-200" : "bg-transparent py-5 border-transparent"
|
||||
)}>
|
||||
<div className="max-w-7xl mx-auto px-6 flex items-center justify-between">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-10 h-10 bg-blue-600 rounded-lg flex items-center justify-center text-white font-bold text-xl">1</div>
|
||||
<span className="text-xl font-bold tracking-tight text-slate-900">OneOS <span className="text-blue-600">Solutions</span></span>
|
||||
</div>
|
||||
|
||||
{/* Desktop Tabs */}
|
||||
<div className="hidden md:flex items-center gap-1 bg-slate-100 p-1 rounded-full">
|
||||
{tabs.map((tab) => (
|
||||
<button
|
||||
key={tab.id}
|
||||
onClick={() => setActiveTab(tab.id)}
|
||||
className={cn(
|
||||
"px-6 py-2 rounded-full text-sm font-medium transition-all",
|
||||
activeTab === tab.id
|
||||
? "bg-white text-blue-600 shadow-sm"
|
||||
: "text-slate-600 hover:text-slate-900"
|
||||
)}
|
||||
>
|
||||
{tab.label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="hidden md:block">
|
||||
<button className="bg-slate-900 text-white px-5 py-2.5 rounded-full text-sm font-medium hover:bg-slate-800 transition-colors">
|
||||
联系我们
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Mobile Menu Toggle */}
|
||||
<button className="md:hidden p-2" onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}>
|
||||
{isMobileMenuOpen ? <X /> : <Menu />}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Mobile Menu */}
|
||||
<AnimatePresence>
|
||||
{isMobileMenuOpen && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: -20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0, y: -20 }}
|
||||
className="absolute top-full left-0 right-0 bg-white border-b border-slate-200 p-6 md:hidden shadow-xl"
|
||||
>
|
||||
<div className="flex flex-col gap-4">
|
||||
{tabs.map((tab) => (
|
||||
<button
|
||||
key={tab.id}
|
||||
onClick={() => {
|
||||
setActiveTab(tab.id);
|
||||
setIsMobileMenuOpen(false);
|
||||
}}
|
||||
className={cn(
|
||||
"text-left py-3 px-4 rounded-xl text-lg font-medium",
|
||||
activeTab === tab.id ? "bg-blue-50 text-blue-600" : "text-slate-600"
|
||||
)}
|
||||
>
|
||||
{tab.label}
|
||||
</button>
|
||||
))}
|
||||
<hr className="border-slate-100" />
|
||||
<button className="bg-blue-600 text-white py-4 rounded-xl font-bold">
|
||||
立即咨询
|
||||
</button>
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</nav>
|
||||
);
|
||||
};
|
||||
|
||||
const Hero = ({ title, subtitle, badge }: { title: string, subtitle: string, badge: string }) => (
|
||||
<section className="relative pt-32 pb-20 md:pt-48 md:pb-32 overflow-hidden">
|
||||
<div className="absolute top-0 left-1/2 -translate-x-1/2 w-full h-full -z-10 opacity-30">
|
||||
<div className="absolute top-[-10%] left-[-10%] w-[40%] h-[40%] bg-blue-400 rounded-full blur-[120px]" />
|
||||
<div className="absolute bottom-[-10%] right-[-10%] w-[40%] h-[40%] bg-indigo-400 rounded-full blur-[120px]" />
|
||||
</div>
|
||||
|
||||
<div className="max-w-7xl mx-auto px-6 text-center">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6 }}
|
||||
>
|
||||
<span className="inline-block px-4 py-1.5 rounded-full bg-blue-50 text-blue-600 text-xs font-bold uppercase tracking-wider mb-6">
|
||||
{badge}
|
||||
</span>
|
||||
<h1 className="text-5xl md:text-7xl font-black text-slate-900 mb-8 leading-[1.1] tracking-tight">
|
||||
{title}
|
||||
</h1>
|
||||
<p className="text-xl text-slate-600 max-w-3xl mx-auto mb-10 leading-relaxed">
|
||||
{subtitle}
|
||||
</p>
|
||||
<div className="flex flex-col sm:flex-row items-center justify-center gap-4">
|
||||
<button className="w-full sm:w-auto bg-blue-600 text-white px-8 py-4 rounded-2xl font-bold text-lg hover:bg-blue-700 transition-all shadow-lg shadow-blue-200 flex items-center justify-center gap-2">
|
||||
获取解决方案 <ArrowRight size={20} />
|
||||
</button>
|
||||
<button className="w-full sm:w-auto bg-white text-slate-900 border border-slate-200 px-8 py-4 rounded-2xl font-bold text-lg hover:bg-slate-50 transition-all">
|
||||
查看演示视频
|
||||
</button>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
|
||||
const FeatureCard = ({ icon: Icon, title, description, delay }: { icon: any, title: string, description: string, delay: number }) => (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.5, delay }}
|
||||
className="bg-white p-8 rounded-3xl border border-slate-100 shadow-sm hover:shadow-xl hover:-translate-y-1 transition-all group"
|
||||
>
|
||||
<div className="w-14 h-14 bg-blue-50 text-blue-600 rounded-2xl flex items-center justify-center mb-6 group-hover:bg-blue-600 group-hover:text-white transition-colors">
|
||||
<Icon size={28} />
|
||||
</div>
|
||||
<h3 className="text-xl font-bold text-slate-900 mb-3">{title}</h3>
|
||||
<p className="text-slate-600 leading-relaxed">{description}</p>
|
||||
</motion.div>
|
||||
);
|
||||
|
||||
const SectionHeading = ({ title, subtitle, centered = true }: { title: string, subtitle?: string, centered?: boolean }) => (
|
||||
<div className={cn("mb-16", centered ? "text-center" : "text-left")}>
|
||||
<h2 className="text-3xl md:text-4xl font-black text-slate-900 mb-4 tracking-tight">{title}</h2>
|
||||
{subtitle && <p className="text-lg text-slate-500 max-w-2xl mx-auto">{subtitle}</p>}
|
||||
</div>
|
||||
);
|
||||
|
||||
const ScreenshotPlaceholder = ({ label, description, src, type = "web" }: { label: string, description: string, src?: string, type?: "web" | "mobile" }) => (
|
||||
<div className={cn(
|
||||
"relative bg-slate-100 rounded-2xl overflow-hidden border border-slate-200 group cursor-pointer shadow-sm",
|
||||
type === "mobile" ? "aspect-[9/19.5] max-w-[280px] mx-auto" : "aspect-video w-full"
|
||||
)}>
|
||||
{src ? (
|
||||
<img
|
||||
src={src}
|
||||
alt={label}
|
||||
referrerPolicy="no-referrer"
|
||||
className="w-full h-full object-cover object-top group-hover:scale-105 transition-transform duration-500"
|
||||
/>
|
||||
) : (
|
||||
<div className="absolute inset-0 flex flex-col items-center justify-center p-6 text-center">
|
||||
<div className="w-16 h-16 bg-white rounded-full flex items-center justify-center text-slate-400 mb-4 shadow-sm group-hover:scale-110 transition-transform">
|
||||
{type === "mobile" ? <Smartphone size={32} /> : <LayoutDashboard size={32} />}
|
||||
</div>
|
||||
<h4 className="font-bold text-slate-900 mb-2">{label}</h4>
|
||||
<p className="text-xs text-slate-500">{description}</p>
|
||||
</div>
|
||||
)}
|
||||
<div className="absolute inset-0 bg-blue-600/0 group-hover:bg-blue-600/5 transition-colors pointer-events-none" />
|
||||
<div className="absolute bottom-4 right-4 bg-white/90 backdrop-blur px-3 py-1 rounded-full text-[10px] font-bold text-slate-600 border border-white/50 shadow-sm z-10">
|
||||
{type === "mobile" ? "移动端界面" : "Web端界面"}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
// --- Main Content Sections ---
|
||||
|
||||
const AssetManagementSystem = () => {
|
||||
return (
|
||||
<div className="space-y-32 pb-20">
|
||||
<Hero
|
||||
badge="OneOS 核心产品"
|
||||
title="企业级资产管理中枢"
|
||||
subtitle="打通资产从“采购入库”到“报废处置”的全生命周期数据链,实现资产的可视化、精细化、智能化管理。"
|
||||
/>
|
||||
|
||||
{/* Value Highlights */}
|
||||
<section className="max-w-7xl mx-auto px-6">
|
||||
<SectionHeading title="核心价值亮点" subtitle="不仅仅是台账记录,更是企业资产运营的决策大脑" />
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
||||
<FeatureCard
|
||||
icon={ClipboardCheck}
|
||||
title="全生命周期闭环"
|
||||
description="覆盖采购、验收、领用、调拨、维修、盘点、折旧至报废全流程,消除管理盲区。"
|
||||
delay={0.1}
|
||||
/>
|
||||
<FeatureCard
|
||||
icon={BarChart3}
|
||||
title="实时可视化大屏"
|
||||
description="提供资产分布热力图、利用率分析、折旧成本报表等多维度视图,辅助资源优化配置。"
|
||||
delay={0.2}
|
||||
/>
|
||||
<FeatureCard
|
||||
icon={AlertCircle}
|
||||
title="智能预警与运维"
|
||||
description="支持设置维保提醒、闲置预警、超期预警等规则引擎,变被动维修为主动预防。"
|
||||
delay={0.3}
|
||||
/>
|
||||
<FeatureCard
|
||||
icon={Smartphone}
|
||||
title="多端协同集成"
|
||||
description="支持PC管理后台 + 移动端扫码操作,无缝对接企业现有ERP、财务及OA系统。"
|
||||
delay={0.4}
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Architecture */}
|
||||
<section className="bg-slate-50 py-24">
|
||||
<div className="max-w-7xl mx-auto px-6">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-16 items-center">
|
||||
<div>
|
||||
<SectionHeading
|
||||
centered={false}
|
||||
title="系统架构概览"
|
||||
subtitle="基于微服务架构,依托OneOS平台强大的底层能力,确保系统的高可用性与扩展性。"
|
||||
/>
|
||||
<div className="space-y-6">
|
||||
{[
|
||||
{ title: "底层平台", desc: "OneOS 主平台提供统一身份认证、消息总线、数据中台支持。" },
|
||||
{ title: "应用层", desc: "模块化设计,包括资产管理、流程审批、报表分析等核心模块。" },
|
||||
{ title: "接入层", desc: "全面支持Web端、移动端及第三方系统API接入。" }
|
||||
].map((item, i) => (
|
||||
<div key={i} className="flex gap-4">
|
||||
<div className="mt-1 flex-shrink-0 w-6 h-6 rounded-full bg-blue-100 text-blue-600 flex items-center justify-center">
|
||||
<CheckCircle2 size={14} />
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-bold text-slate-900">{item.title}</h4>
|
||||
<p className="text-slate-500 text-sm">{item.desc}</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-white p-10 rounded-[40px] shadow-2xl shadow-slate-200 border border-slate-100 relative overflow-hidden">
|
||||
<div className="absolute top-0 right-0 w-32 h-32 bg-blue-50 rounded-bl-full -z-0" />
|
||||
<div className="relative z-10 flex flex-col items-center gap-8">
|
||||
<div className="w-48 h-48 rounded-full border-4 border-dashed border-blue-200 flex items-center justify-center p-4">
|
||||
<div className="w-full h-full bg-blue-600 rounded-full flex flex-col items-center justify-center text-white text-center">
|
||||
<Database size={32} className="mb-2" />
|
||||
<span className="text-xs font-bold uppercase tracking-widest">资产数据中心</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-4 w-full">
|
||||
{['基础数据管理', '业务流程管理', '统计分析', '系统管理'].map((mod) => (
|
||||
<div key={mod} className="bg-slate-50 p-4 rounded-2xl text-center text-sm font-bold text-slate-700 border border-slate-100">
|
||||
{mod}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Modules Showcase */}
|
||||
<section className="max-w-7xl mx-auto px-6">
|
||||
<SectionHeading title="关键功能模块展示" subtitle="直观、易用、专业的管理界面" />
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||
<div className="space-y-4">
|
||||
<ScreenshotPlaceholder
|
||||
label="资产全景视图"
|
||||
description="展示资产总览、分类统计、分布情况。"
|
||||
src="input_file_1.png"
|
||||
/>
|
||||
<div className="px-2">
|
||||
<h4 className="font-bold text-slate-900">1. 资产全景视图</h4>
|
||||
<p className="text-sm text-slate-500">数据大屏或仪表盘。展示资产总金额、分类占比、状态分布图表。</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
<ScreenshotPlaceholder
|
||||
label="资产详情卡片"
|
||||
description="展示单个资产的全息档案。"
|
||||
src="input_file_0.png"
|
||||
/>
|
||||
<div className="px-2">
|
||||
<h4 className="font-bold text-slate-900">2. 资产详情卡片</h4>
|
||||
<p className="text-sm text-slate-500">包含资产编码、位置、责任人、照片、关联文档等全量信息。</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
<ScreenshotPlaceholder
|
||||
label="业务流程引擎"
|
||||
description="展示资产流转的自动化审批。"
|
||||
src="input_file_3.png"
|
||||
/>
|
||||
<div className="px-2">
|
||||
<h4 className="font-bold text-slate-900">3. 业务流程引擎</h4>
|
||||
<p className="text-sm text-slate-500">资产领用、维修申请流转图,清晰显示节点和处理人。</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
<ScreenshotPlaceholder
|
||||
label="移动端操作"
|
||||
description="现场扫码盘点或操作。"
|
||||
type="mobile"
|
||||
src="input_file_4.png"
|
||||
/>
|
||||
<div className="px-2 text-center">
|
||||
<h4 className="font-bold text-slate-900">4. 移动端操作</h4>
|
||||
<p className="text-sm text-slate-500">体现“随时随地,扫码即查”的便捷性。</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-4 md:col-span-2">
|
||||
<ScreenshotPlaceholder
|
||||
label="报表与导出"
|
||||
description="数据统计分析能力。"
|
||||
src="input_file_2.png"
|
||||
/>
|
||||
<div className="px-2">
|
||||
<h4 className="font-bold text-slate-900">5. 报表与导出</h4>
|
||||
<p className="text-sm text-slate-500">报表中心。支持自定义查询条件和一键导出Excel功能。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Security */}
|
||||
<section className="max-w-5xl mx-auto px-6">
|
||||
<div className="bg-slate-900 rounded-[40px] p-12 text-white flex flex-col md:flex-row items-center gap-12">
|
||||
<div className="w-24 h-24 bg-blue-600 rounded-3xl flex items-center justify-center flex-shrink-0">
|
||||
<ShieldCheck size={48} />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-3xl font-bold mb-4">安全与合规</h3>
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-8">
|
||||
<div>
|
||||
<h4 className="text-blue-400 font-bold mb-2">数据安全</h4>
|
||||
<p className="text-slate-400 text-sm leading-relaxed">依托OneOS平台的安全机制,支持数据加密传输与存储,保障企业核心资产数据不外泄。</p>
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="text-blue-400 font-bold mb-2">权限控制</h4>
|
||||
<p className="text-slate-400 text-sm leading-relaxed">细粒度的RBAC权限管理,确保不同角色只能看到和操作被授权的数据,实现管理闭环。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const VehicleRentalSystem = () => {
|
||||
return (
|
||||
<div className="space-y-32 pb-20">
|
||||
<Hero
|
||||
badge="业务能力全景介绍"
|
||||
title="车辆租赁业务管理系统"
|
||||
subtitle="覆盖租赁全生命周期,从业务源头到资金结算的端到端闭环管理,保障业务安全、高效、可追溯。"
|
||||
/>
|
||||
|
||||
{/* Business Cycle */}
|
||||
<section className="max-w-7xl mx-auto px-6">
|
||||
<SectionHeading title="业务闭环:覆盖租赁全生命周期" />
|
||||
<div className="relative">
|
||||
<div className="absolute top-1/2 left-0 right-0 h-1 bg-slate-100 -translate-y-1/2 hidden lg:block" />
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8 relative z-10">
|
||||
{[
|
||||
{ icon: FileText, title: "源头管控", desc: "合同与风控。从客户签约到押金/租金收取,自动关联合同条款,确保资金安全。" },
|
||||
{ icon: Truck, title: "过程执行", desc: "车务管理。涵盖验车、交车、用车、还车等核心环节,数字化固化标准作业程序。" },
|
||||
{ icon: Settings, title: "资金结算", desc: "账务闭环。自动化生成应收应付账单,实现费用、违章、保险等精准核算。" }
|
||||
].map((step, i) => (
|
||||
<div key={i} className="bg-white p-8 rounded-3xl border border-slate-100 shadow-sm text-center">
|
||||
<div className="w-16 h-16 bg-blue-600 text-white rounded-2xl flex items-center justify-center mx-auto mb-6 shadow-lg shadow-blue-100">
|
||||
<step.icon size={32} />
|
||||
</div>
|
||||
<h3 className="text-xl font-bold text-slate-900 mb-3">{step.title}</h3>
|
||||
<p className="text-slate-500 text-sm leading-relaxed">{step.desc}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Core Modules */}
|
||||
<section className="bg-slate-50 py-24">
|
||||
<div className="max-w-7xl mx-auto px-6">
|
||||
<SectionHeading title="核心模块详解" subtitle="专业化模块设计,支撑复杂租赁场景" />
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||
{[
|
||||
{
|
||||
title: "合同与资金管理",
|
||||
tag: "业务基石",
|
||||
items: ["合同全生命周期管理(创建、审批、变更、续签)", "资金流水透明化(租金、押金、违约金自动计算)", "多种支付方式支持,财务系统实时同步"]
|
||||
},
|
||||
{
|
||||
title: "车务与现场管理",
|
||||
tag: "执行核心",
|
||||
items: ["标准化验车流程(拍照上传电子证据,规避纠纷)", "智能调度与交车(车辆状态实时更新,强制证件核对)", "用车监控(集成GPS实时位置与轨迹监控)"]
|
||||
},
|
||||
{
|
||||
title: "异常与售后处理",
|
||||
tag: "风险兜底",
|
||||
items: ["违章与事故处理(记录录入、查询与费用追偿)", "维保与年检自动提醒,形成车辆健康档案", "保险理赔流程清晰指引"]
|
||||
},
|
||||
{
|
||||
title: "结算与报表",
|
||||
tag: "数据决策",
|
||||
items: ["自动化结算(根据里程、时长、违章自动生成结算单)", "多维数据分析看板(利用率、营收、信用分析)", "辅助管理层精准决策"]
|
||||
}
|
||||
].map((mod, i) => (
|
||||
<div key={i} className="bg-white p-10 rounded-[32px] border border-slate-200 shadow-sm">
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<h3 className="text-2xl font-bold text-slate-900">{mod.title}</h3>
|
||||
<span className="px-3 py-1 bg-blue-50 text-blue-600 text-[10px] font-black uppercase rounded-full tracking-wider">{mod.tag}</span>
|
||||
</div>
|
||||
<ul className="space-y-4">
|
||||
{mod.items.map((item, j) => (
|
||||
<li key={j} className="flex gap-3 text-slate-600 text-sm">
|
||||
<div className="mt-1 flex-shrink-0 w-4 h-4 rounded-full bg-blue-100 text-blue-600 flex items-center justify-center">
|
||||
<ChevronRight size={10} />
|
||||
</div>
|
||||
{item}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Why Choose Us */}
|
||||
<section className="max-w-7xl mx-auto px-6">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-16 items-center">
|
||||
<div>
|
||||
<SectionHeading
|
||||
centered={false}
|
||||
title="为什么选择我们的系统?"
|
||||
subtitle="将复杂的租赁流程固化到系统中,降低风险,提升效率。"
|
||||
/>
|
||||
<div className="space-y-8">
|
||||
{[
|
||||
{ title: "业务流程标准化", desc: "降低人为操作失误风险,确保业务合规。" },
|
||||
{ title: "资产安全保障", desc: "验车拍照、GPS监控、违章预警全方位保护。" },
|
||||
{ title: "资金管理零误差", desc: "自动化计费与结算,每一笔收入支出清晰可查。" },
|
||||
{ title: "数据驱动增长", desc: "洞察业务瓶颈,优化运营策略。" }
|
||||
].map((item, i) => (
|
||||
<div key={i} className="flex gap-4">
|
||||
<div className="w-12 h-12 bg-slate-900 text-white rounded-2xl flex items-center justify-center flex-shrink-0">
|
||||
<Zap size={20} />
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="text-lg font-bold text-slate-900">{item.title}</h4>
|
||||
<p className="text-slate-500 text-sm">{item.desc}</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div className="space-y-4 pt-12">
|
||||
<ScreenshotPlaceholder
|
||||
label="移动端验车"
|
||||
description="拍照上传,电子存证"
|
||||
type="mobile"
|
||||
src="input_file_5.png"
|
||||
/>
|
||||
<ScreenshotPlaceholder
|
||||
label="车辆状态看板"
|
||||
description="实时掌握车队动态"
|
||||
src="input_file_0.png"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
<ScreenshotPlaceholder
|
||||
label="合同审批流"
|
||||
description="流程可视化"
|
||||
src="input_file_3.png"
|
||||
/>
|
||||
<ScreenshotPlaceholder
|
||||
label="结算报表"
|
||||
description="一键生成账单"
|
||||
type="mobile"
|
||||
src="input_file_6.png"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const Footer = () => (
|
||||
<footer className="bg-slate-50 border-t border-slate-200 py-20">
|
||||
<div className="max-w-7xl mx-auto px-6">
|
||||
<div className="flex flex-col md:flex-row justify-between items-center gap-8">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-8 h-8 bg-blue-600 rounded-lg flex items-center justify-center text-white font-bold">1</div>
|
||||
<span className="text-lg font-bold tracking-tight text-slate-900">OneOS <span className="text-blue-600">Solutions</span></span>
|
||||
</div>
|
||||
<p className="text-slate-500 text-sm">© 2026 OneOS 资产管理系统. 保留所有权利.</p>
|
||||
<div className="flex gap-6">
|
||||
<a href="#" className="text-slate-400 hover:text-blue-600 transition-colors">服务条款</a>
|
||||
<a href="#" className="text-slate-400 hover:text-blue-600 transition-colors">隐私政策</a>
|
||||
<a href="#" className="text-slate-400 hover:text-blue-600 transition-colors">联系我们</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
|
||||
// --- Main App ---
|
||||
|
||||
export default function App() {
|
||||
const [activeTab, setActiveTab] = useState('asset');
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-white font-sans selection:bg-blue-100 selection:text-blue-600">
|
||||
<Navbar activeTab={activeTab} setActiveTab={setActiveTab} />
|
||||
|
||||
<main>
|
||||
<AnimatePresence mode="wait">
|
||||
<motion.div
|
||||
key={activeTab}
|
||||
initial={{ opacity: 0, x: 10 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
exit={{ opacity: 0, x: -10 }}
|
||||
transition={{ duration: 0.4 }}
|
||||
>
|
||||
{activeTab === 'asset' ? <AssetManagementSystem /> : <VehicleRentalSystem />}
|
||||
</motion.div>
|
||||
</AnimatePresence>
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
12
src/index.css
Normal file
12
src/index.css
Normal file
@@ -0,0 +1,12 @@
|
||||
@import "tailwindcss";
|
||||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&display=swap');
|
||||
|
||||
@theme {
|
||||
--font-sans: "Inter", ui-sans-serif, system-ui, sans-serif;
|
||||
}
|
||||
|
||||
@layer base {
|
||||
body {
|
||||
@apply antialiased text-slate-900;
|
||||
}
|
||||
}
|
||||
10
src/main.tsx
Normal file
10
src/main.tsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import {StrictMode} from 'react';
|
||||
import {createRoot} from 'react-dom/client';
|
||||
import App from './App.tsx';
|
||||
import './index.css';
|
||||
|
||||
createRoot(document.getElementById('root')!).render(
|
||||
<StrictMode>
|
||||
<App />
|
||||
</StrictMode>,
|
||||
);
|
||||
26
tsconfig.json
Normal file
26
tsconfig.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"experimentalDecorators": true,
|
||||
"useDefineForClassFields": false,
|
||||
"module": "ESNext",
|
||||
"lib": [
|
||||
"ES2022",
|
||||
"DOM",
|
||||
"DOM.Iterable"
|
||||
],
|
||||
"skipLibCheck": true,
|
||||
"moduleResolution": "bundler",
|
||||
"isolatedModules": true,
|
||||
"moduleDetection": "force",
|
||||
"allowJs": true,
|
||||
"jsx": "react-jsx",
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"./*"
|
||||
]
|
||||
},
|
||||
"allowImportingTsExtensions": true,
|
||||
"noEmit": true
|
||||
}
|
||||
}
|
||||
24
vite.config.ts
Normal file
24
vite.config.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import tailwindcss from '@tailwindcss/vite';
|
||||
import react from '@vitejs/plugin-react';
|
||||
import path from 'path';
|
||||
import {defineConfig, loadEnv} from 'vite';
|
||||
|
||||
export default defineConfig(({mode}) => {
|
||||
const env = loadEnv(mode, '.', '');
|
||||
return {
|
||||
plugins: [react(), tailwindcss()],
|
||||
define: {
|
||||
'process.env.GEMINI_API_KEY': JSON.stringify(env.GEMINI_API_KEY),
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.resolve(__dirname, '.'),
|
||||
},
|
||||
},
|
||||
server: {
|
||||
// HMR is disabled in AI Studio via DISABLE_HMR env var.
|
||||
// Do not modifyâfile watching is disabled to prevent flickering during agent edits.
|
||||
hmr: process.env.DISABLE_HMR !== 'true',
|
||||
},
|
||||
};
|
||||
});
|
||||
Reference in New Issue
Block a user