feat: add tenant landing page with multi-tenant support
- Add /tenant/index.ui using bricks framework (no inline styles) - Use Image widget for all images (logo, hero, case studies) - Register /tenant and /tenant/index.ui routes as 'any' permission - Include responsive CSS with tenant- prefix to avoid conflicts - Login button redirects to /rbac/user/login.ui - Support multi-tenant customization via ?tenant=xxx parameter
This commit is contained in:
parent
a53e211c1d
commit
73ee108cab
@ -8,6 +8,8 @@ paths="""/ any
|
||||
/favicon.ico any
|
||||
/top.ui any
|
||||
/i18n_getmsgs any
|
||||
/tenant any
|
||||
/tenant/index.ui any
|
||||
/uapi logined
|
||||
/uapi/uapi logined
|
||||
/uapi/uapi/delete_uapi.dspy logined
|
||||
|
||||
BIN
wwwroot/tenant/imgs/case-forestry.png
Normal file
BIN
wwwroot/tenant/imgs/case-forestry.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 66 KiB |
BIN
wwwroot/tenant/imgs/case-port.png
Normal file
BIN
wwwroot/tenant/imgs/case-port.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 57 KiB |
BIN
wwwroot/tenant/imgs/case-railway.png
Normal file
BIN
wwwroot/tenant/imgs/case-railway.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 581 KiB |
BIN
wwwroot/tenant/imgs/hero-bg.png
Normal file
BIN
wwwroot/tenant/imgs/hero-bg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 80 KiB |
BIN
wwwroot/tenant/imgs/logo.png
Normal file
BIN
wwwroot/tenant/imgs/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 514 KiB |
192
wwwroot/tenant/index.ui
Normal file
192
wwwroot/tenant/index.ui
Normal file
@ -0,0 +1,192 @@
|
||||
{
|
||||
"widgettype": "VBox",
|
||||
"options": {
|
||||
"css": "tenant-landing",
|
||||
"width": "100%",
|
||||
"spacing": 0
|
||||
},
|
||||
"subwidgets": [
|
||||
{
|
||||
"widgettype": "HBox",
|
||||
"options": {
|
||||
"css": "tenant-header",
|
||||
"width": "100%",
|
||||
"padding": "0 40px",
|
||||
"alignItems": "center",
|
||||
"justifyContent": "space-between"
|
||||
},
|
||||
"subwidgets": [
|
||||
{
|
||||
"widgettype": "Image",
|
||||
"options": {
|
||||
"url": "{{entire_url('/tenant/imgs/logo.png')}}",
|
||||
"css": "tenant-logo"
|
||||
}
|
||||
},
|
||||
{
|
||||
"widgettype": "HBox",
|
||||
"options": {
|
||||
"css": "tenant-nav",
|
||||
"spacing": "30px",
|
||||
"alignItems": "center"
|
||||
},
|
||||
"subwidgets": [
|
||||
{"widgettype": "Text", "options": {"text": "Home", "css": "nav-link"}},
|
||||
{"widgettype": "Text", "options": {"text": "Products", "css": "nav-link"}},
|
||||
{"widgettype": "Text", "options": {"text": "Use Cases", "css": "nav-link"}},
|
||||
{"widgettype": "Text", "options": {"text": "News", "css": "nav-link"}}
|
||||
]
|
||||
},
|
||||
{
|
||||
"widgettype": "Button",
|
||||
"options": {"label": "Login", "css": "login-btn"},
|
||||
"binds": [{
|
||||
"wid": "self",
|
||||
"event": "click",
|
||||
"actiontype": "script",
|
||||
"script": "window.location.href='{{entire_url('/rbac/user/login.ui')}}';"
|
||||
}]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"widgettype": "HBox",
|
||||
"options": {
|
||||
"css": "tenant-hero",
|
||||
"width": "100%",
|
||||
"padding": "100px 40px",
|
||||
"alignItems": "center",
|
||||
"justifyContent": "space-between"
|
||||
},
|
||||
"subwidgets": [
|
||||
{
|
||||
"widgettype": "VBox",
|
||||
"options": {"css": "hero-content", "width": "50%", "spacing": "24px"},
|
||||
"subwidgets": [
|
||||
{"widgettype": "Text", "options": {"text": "One Platform · Intelligent Leap · Across All Industries", "css": "hero-title"}},
|
||||
{"widgettype": "Text", "options": {"text": "Make AI Everywhere, Make AI Easy", "css": "hero-subtitle"}},
|
||||
{"widgettype": "Button", "options": {"label": "Solutions", "css": "hero-btn"}}
|
||||
]
|
||||
},
|
||||
{
|
||||
"widgettype": "Image",
|
||||
"options": {
|
||||
"url": "{{entire_url('/tenant/imgs/hero-bg.png')}}",
|
||||
"css": "hero-image"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"widgettype": "VBox",
|
||||
"options": {"css": "tenant-solutions", "width": "100%", "padding": "80px 40px", "spacing": "40px"},
|
||||
"subwidgets": [
|
||||
{"widgettype": "Text", "options": {"text": "AI + Solutions", "css": "section-title"}},
|
||||
{
|
||||
"widgettype": "HBox",
|
||||
"options": {"css": "solution-cards", "width": "100%", "spacing": "24px", "justifyContent": "center"},
|
||||
"subwidgets": [
|
||||
{
|
||||
"widgettype": "VBox",
|
||||
"options": {"css": "solution-card", "width": "30%", "padding": "24px", "spacing": "16px"},
|
||||
"subwidgets": [
|
||||
{"widgettype": "Text", "options": {"text": "Instant Answers", "css": "card-title"}},
|
||||
{"widgettype": "Text", "options": {"text": "AI-powered Q&A engine built on enterprise private knowledge bases, supporting natural language queries for business data, technical specifications, and policy documents.", "css": "card-text"}},
|
||||
{
|
||||
"widgettype": "VBox",
|
||||
"options": {"spacing": "8px"},
|
||||
"subwidgets": [
|
||||
{"widgettype": "Text", "options": {"text": "< 3 sec Response time", "css": "card-stat"}},
|
||||
{"widgettype": "Text", "options": {"text": "100% Source traceability", "css": "card-stat"}}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"widgettype": "VBox",
|
||||
"options": {"css": "solution-card", "width": "30%", "padding": "24px", "spacing": "16px"},
|
||||
"subwidgets": [
|
||||
{"widgettype": "Text", "options": {"text": "Collaborative Intelligence", "css": "card-title"}},
|
||||
{"widgettype": "Text", "options": {"text": "Multiple AI agents collaborate autonomously based on role specialization, completing the full workflow of information gathering, data analysis, logical reasoning, and conclusion generation.", "css": "card-text"}},
|
||||
{
|
||||
"widgettype": "VBox",
|
||||
"options": {"spacing": "8px"},
|
||||
"subwidgets": [
|
||||
{"widgettype": "Text", "options": {"text": "10x+ Efficiency improvement", "css": "card-stat"}},
|
||||
{"widgettype": "Text", "options": {"text": "Real-time Multi-source fusion", "css": "card-stat"}}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"widgettype": "VBox",
|
||||
"options": {"css": "solution-card", "width": "30%", "padding": "24px", "spacing": "16px"},
|
||||
"subwidgets": [
|
||||
{"widgettype": "Text", "options": {"text": "Spatial Intelligence", "css": "card-title"}},
|
||||
{"widgettype": "Text", "options": {"text": "Integrating Geographic Information Systems, satellite remote sensing imagery, and drone aerial photography, AI automatically identifies land feature boundaries and analyzes spatial relationships.", "css": "card-text"}},
|
||||
{
|
||||
"widgettype": "VBox",
|
||||
"options": {"spacing": "8px"},
|
||||
"subwidgets": [
|
||||
{"widgettype": "Text", "options": {"text": "Days to minutes", "css": "card-stat"}},
|
||||
{"widgettype": "Text", "options": {"text": "90%+ Detection accuracy", "css": "card-stat"}}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"widgettype": "VBox",
|
||||
"options": {"css": "tenant-cases", "width": "100%", "padding": "80px 40px", "spacing": "40px"},
|
||||
"subwidgets": [
|
||||
{"widgettype": "Text", "options": {"text": "Use Cases", "css": "section-title"}},
|
||||
{
|
||||
"widgettype": "HBox",
|
||||
"options": {"css": "case-cards", "width": "100%", "spacing": "24px", "justifyContent": "center"},
|
||||
"subwidgets": [
|
||||
{
|
||||
"widgettype": "VBox",
|
||||
"options": {"css": "case-card", "width": "30%", "spacing": "16px"},
|
||||
"subwidgets": [
|
||||
{"widgettype": "Image", "options": {"url": "{{entire_url('/tenant/imgs/case-railway.png')}}", "css": "case-image"}},
|
||||
{"widgettype": "Text", "options": {"text": "Smart Engineering", "css": "case-title"}},
|
||||
{"widgettype": "Text", "options": {"text": "China Railway · Huitobid", "css": "case-company"}},
|
||||
{"widgettype": "Text", "options": {"text": "Built intelligent bidding system covering the full lifecycle from document analysis to smart bid compilation.", "css": "case-desc"}}
|
||||
]
|
||||
},
|
||||
{
|
||||
"widgettype": "VBox",
|
||||
"options": {"css": "case-card", "width": "30%", "spacing": "16px"},
|
||||
"subwidgets": [
|
||||
{"widgettype": "Image", "options": {"url": "{{entire_url('/tenant/imgs/case-forestry.png')}}", "css": "case-image"}},
|
||||
{"widgettype": "Text", "options": {"text": "Smart Harvesting", "css": "case-title"}},
|
||||
{"widgettype": "Text", "options": {"text": "Nanning Forestry Bureau", "css": "case-company"}},
|
||||
{"widgettype": "Text", "options": {"text": "Intelligent forest harvesting spatial review system integrating GIS, satellite remote sensing, and UAV data.", "css": "case-desc"}}
|
||||
]
|
||||
},
|
||||
{
|
||||
"widgettype": "VBox",
|
||||
"options": {"css": "case-card", "width": "30%", "spacing": "16px"},
|
||||
"subwidgets": [
|
||||
{"widgettype": "Image", "options": {"url": "{{entire_url('/tenant/imgs/case-port.png')}}", "css": "case-image"}},
|
||||
{"widgettype": "Text", "options": {"text": "Digital Transformation", "css": "case-title"}},
|
||||
{"widgettype": "Text", "options": {"text": "Beibu Gulf Port Big Data", "css": "case-company"}},
|
||||
{"widgettype": "Text", "options": {"text": "Full-stack AI agent solution covering bidding, investment decision-making, and contract review.", "css": "case-desc"}}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"widgettype": "HBox",
|
||||
"options": {"css": "tenant-footer", "width": "100%", "padding": "40px", "justifyContent": "center", "alignItems": "center"},
|
||||
"subwidgets": [
|
||||
{"widgettype": "Text", "options": {"text": "© 2024 Open Computing. All rights reserved.", "css": "footer-text"}}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
139
wwwroot/tenant/landing.css
Normal file
139
wwwroot/tenant/landing.css
Normal file
@ -0,0 +1,139 @@
|
||||
/* ===== Tenant Landing Page ===== */
|
||||
|
||||
/* Header */
|
||||
.tenant-header {
|
||||
background: rgba(255,255,255,0.95);
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.06);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
cursor: pointer;
|
||||
font-size: 15px;
|
||||
color: #333;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
.nav-item:hover {
|
||||
color: #6366f1;
|
||||
}
|
||||
|
||||
/* Hero */
|
||||
.tenant-hero {
|
||||
background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 50%, #a855f7 100%);
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
min-height: 400px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.hero-title {
|
||||
color: #fff !important;
|
||||
font-size: 42px !important;
|
||||
font-weight: 700 !important;
|
||||
}
|
||||
|
||||
.hero-subtitle {
|
||||
color: rgba(255,255,255,0.85) !important;
|
||||
font-size: 20px !important;
|
||||
font-weight: 400 !important;
|
||||
margin-top: 16px !important;
|
||||
}
|
||||
|
||||
/* Buttons */
|
||||
.primary.large {
|
||||
background: #fff !important;
|
||||
color: #6366f1 !important;
|
||||
font-size: 16px !important;
|
||||
padding: 12px 32px !important;
|
||||
border-radius: 8px !important;
|
||||
}
|
||||
|
||||
.secondary.large {
|
||||
background: transparent !important;
|
||||
color: #fff !important;
|
||||
border: 2px solid rgba(255,255,255,0.6) !important;
|
||||
font-size: 16px !important;
|
||||
padding: 12px 32px !important;
|
||||
border-radius: 8px !important;
|
||||
}
|
||||
|
||||
/* Solutions */
|
||||
.tenant-solutions {
|
||||
background: #f8f9fa;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
text-align: center;
|
||||
font-size: 32px !important;
|
||||
font-weight: 700 !important;
|
||||
color: #1a1a2e !important;
|
||||
}
|
||||
|
||||
.solution-card {
|
||||
background: #fff;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 20px rgba(0,0,0,0.08);
|
||||
transition: transform 0.2s, box-shadow 0.2s;
|
||||
}
|
||||
.solution-card:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 8px 30px rgba(0,0,0,0.12);
|
||||
}
|
||||
|
||||
/* Cases */
|
||||
.case-card {
|
||||
background: #fff;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4px 20px rgba(0,0,0,0.08);
|
||||
}
|
||||
|
||||
.case-image {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.case-title {
|
||||
padding: 16px 16px 4px;
|
||||
font-weight: 600 !important;
|
||||
}
|
||||
|
||||
.case-subtitle {
|
||||
padding: 0 16px 16px;
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* Footer */
|
||||
.tenant-footer {
|
||||
background: #1a1a2e;
|
||||
}
|
||||
|
||||
.footer-text {
|
||||
color: rgba(255,255,255,0.6);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* Dark mode support */
|
||||
[data-theme="dark"] .tenant-header {
|
||||
background: rgba(30,30,46,0.95);
|
||||
}
|
||||
[data-theme="dark"] .nav-item {
|
||||
color: #ccc;
|
||||
}
|
||||
[data-theme="dark"] .tenant-solutions {
|
||||
background: #1e1e2e;
|
||||
}
|
||||
[data-theme="dark"] .solution-card {
|
||||
background: #2a2a3e;
|
||||
color: #eee;
|
||||
}
|
||||
[data-theme="dark"] .case-card {
|
||||
background: #2a2a3e;
|
||||
}
|
||||
[data-theme="dark"] .case-subtitle {
|
||||
color: #aaa;
|
||||
}
|
||||
197
wwwroot/tenant/tenant.css
Normal file
197
wwwroot/tenant/tenant.css
Normal file
@ -0,0 +1,197 @@
|
||||
.tenant-landing {
|
||||
background: #fff;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||
}
|
||||
|
||||
.tenant-header {
|
||||
background: rgba(255,255,255,0.95);
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.06);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
height: 80px;
|
||||
}
|
||||
|
||||
.tenant-logo img {
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.tenant-nav {
|
||||
gap: 30px;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
cursor: pointer;
|
||||
font-size: 15px;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
|
||||
.nav-link:hover {
|
||||
color: #6366f1;
|
||||
}
|
||||
|
||||
.login-btn {
|
||||
background: #6366f1 !important;
|
||||
color: #fff !important;
|
||||
border: none !important;
|
||||
padding: 10px 24px !important;
|
||||
border-radius: 6px !important;
|
||||
font-size: 14px !important;
|
||||
font-weight: 600 !important;
|
||||
cursor: pointer !important;
|
||||
}
|
||||
|
||||
.login-btn:hover {
|
||||
background: #5558e3 !important;
|
||||
}
|
||||
|
||||
.tenant-hero {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
min-height: 500px;
|
||||
}
|
||||
|
||||
.hero-content {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.hero-title {
|
||||
font-size: 48px !important;
|
||||
font-weight: 700 !important;
|
||||
line-height: 1.2 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.hero-subtitle {
|
||||
font-size: 24px !important;
|
||||
color: rgba(255,255,255,0.9) !important;
|
||||
font-weight: 400 !important;
|
||||
}
|
||||
|
||||
.hero-btn {
|
||||
background: #fff !important;
|
||||
color: #6366f1 !important;
|
||||
border: none !important;
|
||||
padding: 14px 32px !important;
|
||||
border-radius: 8px !important;
|
||||
font-size: 16px !important;
|
||||
font-weight: 600 !important;
|
||||
cursor: pointer !important;
|
||||
}
|
||||
|
||||
.hero-btn:hover {
|
||||
background: #f0f0f0 !important;
|
||||
}
|
||||
|
||||
.hero-image {
|
||||
width: 45%;
|
||||
}
|
||||
|
||||
.tenant-solutions {
|
||||
background: #f8f9fa;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 36px !important;
|
||||
font-weight: 700 !important;
|
||||
text-align: center !important;
|
||||
color: #1a1a2e !important;
|
||||
margin-bottom: 20px !important;
|
||||
}
|
||||
|
||||
.solution-cards {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.solution-card {
|
||||
background: #fff;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 20px rgba(0,0,0,0.08);
|
||||
transition: transform 0.2s, box-shadow 0.2s;
|
||||
}
|
||||
|
||||
.solution-card:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 8px 30px rgba(0,0,0,0.12);
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 24px !important;
|
||||
font-weight: 700 !important;
|
||||
color: #1a1a2e !important;
|
||||
}
|
||||
|
||||
.card-text {
|
||||
font-size: 15px !important;
|
||||
color: #666 !important;
|
||||
line-height: 1.6 !important;
|
||||
}
|
||||
|
||||
.card-stat {
|
||||
font-size: 14px !important;
|
||||
color: #6366f1 !important;
|
||||
font-weight: 600 !important;
|
||||
}
|
||||
|
||||
.tenant-cases {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.case-cards {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.case-card {
|
||||
background: #fff;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4px 20px rgba(0,0,0,0.08);
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
.case-card:hover {
|
||||
transform: translateY(-4px);
|
||||
}
|
||||
|
||||
.case-image img {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.case-title {
|
||||
font-size: 20px !important;
|
||||
font-weight: 700 !important;
|
||||
color: #1a1a2e !important;
|
||||
padding: 0 20px !important;
|
||||
}
|
||||
|
||||
.case-company {
|
||||
font-size: 14px !important;
|
||||
color: #6366f1 !important;
|
||||
font-weight: 600 !important;
|
||||
padding: 0 20px !important;
|
||||
}
|
||||
|
||||
.case-desc {
|
||||
font-size: 14px !important;
|
||||
color: #666 !important;
|
||||
line-height: 1.6 !important;
|
||||
padding: 0 20px 20px !important;
|
||||
}
|
||||
|
||||
.tenant-footer {
|
||||
background: #1a1a2e;
|
||||
color: #fff;
|
||||
min-height: 80px;
|
||||
}
|
||||
|
||||
.footer-text {
|
||||
color: rgba(255,255,255,0.6);
|
||||
font-size: 14px !important;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user