初始化2
This commit is contained in:
149
app/utils/appEntry.ts
Normal file
149
app/utils/appEntry.ts
Normal file
@@ -0,0 +1,149 @@
|
||||
import type { AppProduct } from '@/api/app/appProduct/model'
|
||||
import { APP_TYPE } from '@/api/app/appProduct/model'
|
||||
|
||||
/** 入口动作类型 */
|
||||
export type EntryType =
|
||||
| 'visit-site' // 访问网站
|
||||
| 'scan-qr' // 扫码体验(小程序)
|
||||
| 'download' // 下载安装
|
||||
| 'admin' // 管理后台
|
||||
|
||||
/** 单个入口配置 */
|
||||
export interface AppEntry {
|
||||
type: EntryType
|
||||
label: string
|
||||
/** Ant Design 图标组件名 */
|
||||
icon: string
|
||||
url?: string
|
||||
available: boolean
|
||||
isPrimary: boolean
|
||||
}
|
||||
|
||||
/** 扫码提示文案映射 */
|
||||
const SCAN_TIPS: Record<number, string> = {
|
||||
[APP_TYPE.WECHAT_MP]: '打开微信扫一扫体验',
|
||||
[APP_TYPE.DOUYIN_MP]: '打开抖音扫一扫体验',
|
||||
[APP_TYPE.BAIDU_MP]: '打开百度APP扫一扫体验',
|
||||
[APP_TYPE.ALIPAY_MP]: '打开支付宝扫一扫体验',
|
||||
}
|
||||
|
||||
/** 小程序 appType 集合 */
|
||||
const MINI_PROGRAM_TYPES = new Set([
|
||||
APP_TYPE.WECHAT_MP,
|
||||
APP_TYPE.DOUYIN_MP,
|
||||
APP_TYPE.BAIDU_MP,
|
||||
APP_TYPE.ALIPAY_MP,
|
||||
])
|
||||
|
||||
/** 移动端/桌面端 appType 集合 */
|
||||
const INSTALLABLE_TYPES = new Set([
|
||||
APP_TYPE.ANDROID,
|
||||
APP_TYPE.IOS,
|
||||
APP_TYPE.MACOS,
|
||||
APP_TYPE.WINDOWS,
|
||||
])
|
||||
|
||||
/**
|
||||
* 解析 Web 应用的前台 URL
|
||||
* 优先使用显式配置的 homeUrl,否则用 domain + prefix 拼接
|
||||
*/
|
||||
export function resolveWebHomeUrl(app: AppProduct): string | null {
|
||||
if (app.homeUrl) return app.homeUrl
|
||||
if (app.domain) {
|
||||
const prefix = app.prefix ? `/${app.prefix.replace(/^\//, '')}` : ''
|
||||
return `https://${app.domain}${prefix}`
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取应用的所有可用入口(按优先级排列)
|
||||
*/
|
||||
export function getAppEntries(app: AppProduct): AppEntry[] {
|
||||
const entries: AppEntry[] = []
|
||||
const type = app.appType
|
||||
|
||||
// 1. 访问网站(仅 Web 应用)
|
||||
if (type === APP_TYPE.WEBSITE) {
|
||||
const url = resolveWebHomeUrl(app)
|
||||
entries.push({
|
||||
type: 'visit-site',
|
||||
label: '访问网站',
|
||||
icon: 'GlobalOutlined',
|
||||
url: url || undefined,
|
||||
available: !!url,
|
||||
isPrimary: true,
|
||||
})
|
||||
}
|
||||
|
||||
// 2. 扫码体验(小程序类型)
|
||||
if (type && MINI_PROGRAM_TYPES.has(type)) {
|
||||
entries.push({
|
||||
type: 'scan-qr',
|
||||
label: '扫码体验',
|
||||
icon: 'QrcodeOutlined',
|
||||
url: app.qrcode,
|
||||
available: !!app.qrcode,
|
||||
isPrimary: true,
|
||||
})
|
||||
}
|
||||
|
||||
// 3. 下载安装(移动端 / 桌面端)
|
||||
if (type && INSTALLABLE_TYPES.has(type)) {
|
||||
entries.push({
|
||||
type: 'download',
|
||||
label: '下载安装',
|
||||
icon: 'DownloadOutlined',
|
||||
url: app.downloadUrl,
|
||||
available: !!app.downloadUrl,
|
||||
isPrimary: true,
|
||||
})
|
||||
}
|
||||
|
||||
// 4. 管理后台(所有类型通用)
|
||||
entries.push({
|
||||
type: 'admin',
|
||||
label: '管理后台',
|
||||
icon: 'SettingOutlined',
|
||||
url: app.adminUrl,
|
||||
available: !!app.adminUrl,
|
||||
// 插件的后台即主入口
|
||||
isPrimary: type === APP_TYPE.PLUGIN,
|
||||
})
|
||||
|
||||
return entries
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取主入口
|
||||
*/
|
||||
export function getPrimaryEntry(app: AppProduct): AppEntry | null {
|
||||
return getAppEntries(app).find(e => e.isPrimary && e.available) || null
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取扫码提示文案
|
||||
*/
|
||||
export function getScanTip(appType: number): string {
|
||||
return SCAN_TIPS[appType] || '扫一扫体验'
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行入口动作(返回是否由调用方自行处理,如扫码弹窗)
|
||||
*/
|
||||
export function executeEntry(entry: AppEntry): boolean {
|
||||
if (!entry.available) return false
|
||||
|
||||
switch (entry.type) {
|
||||
case 'visit-site':
|
||||
case 'download':
|
||||
case 'admin':
|
||||
window.open(entry.url, '_blank', 'noreferrer')
|
||||
return false
|
||||
case 'scan-qr':
|
||||
// 需要调用方弹出二维码弹窗
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user