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:
root
2026-02-24 17:57:25 +08:00
commit 8d78e18267
121 changed files with 18563 additions and 0 deletions
+92
View File
@@ -0,0 +1,92 @@
/**
* 飞书 SDK 封装
*/
export const FeishuSDK = {
/**
* 判断是否在飞书环境
*/
isFeishuEnv(): boolean {
return !!(window as any).h5panel || !!(window as any).tt
},
/**
* 获取免登授权码
*/
async getAuthCode(): Promise<string> {
return new Promise((resolve, reject) => {
if (!this.isFeishuEnv()) {
reject(new Error('Not in Feishu environment'))
return
}
try {
const tt = (window as any).tt || (window as any).h5panel
tt.ready(() => {
tt.requestAuthCode({
success: (res: { authCode: string }) => {
resolve(res.authCode)
},
fail: (err: Error) => {
reject(err)
},
})
})
} catch (error) {
reject(error)
}
})
},
/**
* 获取当前租户信息(用于后端识别公司)
*/
getTenantContext(): { tenantKey?: string } {
if (!this.isFeishuEnv()) {
return {}
}
try {
const tt = (window as any).tt || (window as any).h5panel
// 飞书容器中的租户信息
return {
tenantKey: tt?.tenantKey || '',
}
} catch {
return {}
}
},
/**
* 初始化飞书 JSAPI
*/
async init(): Promise<void> {
if (!this.isFeishuEnv()) {
console.log('Not in Feishu environment, skip initialization')
return
}
return new Promise((resolve, reject) => {
try {
const tt = (window as any).tt || (window as any).h5panel
tt.ready(() => {
console.log('Feishu JSAPI initialized')
resolve()
})
tt.error((err: Error) => {
console.error('Feishu JSAPI error:', err)
reject(err)
})
} catch (error) {
reject(error)
}
})
},
}
// 声明飞书全局类型
declare global {
interface Window {
tt?: any
h5panel?: any
}
}
+35
View File
@@ -0,0 +1,35 @@
/**
* 动态设置根字体大小,实现移动端适配
*/
export function setRem(): void {
// 设计稿宽度
const designWidth = 375 // iPhone 6/7/8 的宽度
// 基础字体大小
const baseFontSize = 16
// 获取当前设备宽度
const deviceWidth = document.documentElement.clientWidth || window.innerWidth
// 计算缩放比例
const scale = deviceWidth / designWidth
// 设置根字体大小(最大不超过 20px,最小不小于 12px)
const fontSize = Math.min(Math.max(scale * baseFontSize, 12), 20)
document.documentElement.style.fontSize = fontSize + 'px'
console.log(`设备宽度: ${deviceWidth}px, 根字体: ${fontSize}px`)
}
/**
* 初始化 rem 适配
*/
export function initRem(): void {
setRem()
// 监听窗口大小变化
window.addEventListener('resize', setRem)
// 监听设备方向变化
window.addEventListener('orientationchange', setRem)
}