Initial commit: X-Server Mobile enterprise tool system
- Frontend: React 18 + TypeScript + Vite + Ant Design Mobile - Backend: PHP 8.5 + Webman 2.x + MySQL + Redis - i18n support: Chinese, English, Russian, Spanish, French - Approval workflow engine - Docker development environment - Feishu integration Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
.apps {
|
||||
min-height: 100vh;
|
||||
padding: 16px;
|
||||
padding-bottom: calc(16px + env(safe-area-inset-bottom));
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.header {
|
||||
margin-bottom: 20px;
|
||||
padding: 16px;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
border-radius: 12px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.header h1 {
|
||||
margin: 0 0 4px 0;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.header p {
|
||||
margin: 0;
|
||||
font-size: 13px;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.appCard {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 16px 8px;
|
||||
background: #fff;
|
||||
border-radius: 12px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.appCard:active {
|
||||
transform: scale(0.95);
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
.appIcon {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
border-radius: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.appInfo {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.appLabel {
|
||||
display: block;
|
||||
font-size: 13px;
|
||||
color: #262626;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.appDesc {
|
||||
display: block;
|
||||
font-size: 11px;
|
||||
color: #8c8c8c;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.safeArea {
|
||||
height: 16px;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
import styles from './apps.module.css'
|
||||
|
||||
interface AppItem {
|
||||
id: string
|
||||
icon: string
|
||||
label: string
|
||||
path: string
|
||||
color: string
|
||||
description?: string
|
||||
}
|
||||
|
||||
const apps: AppItem[] = [
|
||||
{ id: '1', icon: '✈️', label: '出差申请', path: '/business-trip/apply', color: '#1677ff', description: '提交出差申请' },
|
||||
{ id: '2', icon: '📝', label: '采购申请', path: '/purchase/apply', color: '#52c41a', description: '物品采购审批' },
|
||||
{ id: '3', icon: '🏠', label: '会议室', path: '/meeting-room', color: '#faad14', description: '会议室预定' },
|
||||
{ id: '4', icon: '📅', label: '日程管理', path: '/schedule', color: '#722ed1', description: '个人日程安排' },
|
||||
{ id: '5', icon: '💰', label: '报销申请', path: '/expense/apply', color: '#eb2f96', description: '费用报销审批' },
|
||||
{ id: '6', icon: '📋', label: '请假申请', path: '/leave/apply', color: '#13c2c2', description: '请假审批' },
|
||||
{ id: '7', icon: '🚗', label: '用车申请', path: '/car/apply', color: '#f759ab', description: '公车使用申请' },
|
||||
{ id: '8', icon: '🎁', label: '礼品申请', path: '/gift/apply', color: '#ff7a45', description: '礼品采购申请' },
|
||||
{ id: '9', icon: '📊', label: '数据报表', path: '/reports', color: '#1890ff', description: '业务数据统计' },
|
||||
{ id: '10', icon: '👥', label: '通讯录', path: '/contacts', color: '#096dd9', description: '内部通讯录' },
|
||||
{ id: '11', icon: '📁', label: '文件中心', path: '/files', color: '#595959', description: '文件共享管理' },
|
||||
{ id: '12', icon: '⚙️', label: '系统设置', path: '/settings', color: '#8c8c8c', description: '系统偏好设置' },
|
||||
]
|
||||
|
||||
export default function Apps() {
|
||||
const handleAppClick = (app: AppItem) => {
|
||||
// TODO: 跳转到应用页面
|
||||
console.log('点击应用:', app)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.apps}>
|
||||
<div className={styles.header}>
|
||||
<h1>应用中心</h1>
|
||||
<p>选择你需要的功能</p>
|
||||
</div>
|
||||
|
||||
<div className={styles.grid}>
|
||||
{apps.map((app) => (
|
||||
<div
|
||||
key={app.id}
|
||||
className={styles.appCard}
|
||||
onClick={() => handleAppClick(app)}
|
||||
>
|
||||
<div className={styles.appIcon} style={{ backgroundColor: `${app.color}15` }}>
|
||||
<span style={{ fontSize: 32, color: app.color }}>{app.icon}</span>
|
||||
</div>
|
||||
<div className={styles.appInfo}>
|
||||
<span className={styles.appLabel}>{app.label}</span>
|
||||
{app.description && (
|
||||
<span className={styles.appDesc}>{app.description}</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* 底部安全区域 */}
|
||||
<div className={styles.safeArea} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user