|  | @@ -1,5 +1,6 @@
 | 
	
		
			
				|  |  |  import { Component, signal } from '@angular/core';
 | 
	
		
			
				|  |  |  import { Router, RouterModule, RouterOutlet } from '@angular/router';
 | 
	
		
			
				|  |  | +import { AlertController } from '@ionic/angular/standalone';
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  @Component({
 | 
	
		
			
				|  |  |    selector: 'app-root',
 | 
	
	
		
			
				|  | @@ -13,10 +14,13 @@ export class App {
 | 
	
		
			
				|  |  |    protected readonly title = signal('yss-project');
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    constructor(
 | 
	
		
			
				|  |  | -    private router: Router
 | 
	
		
			
				|  |  | +    private router: Router,
 | 
	
		
			
				|  |  | +    private alertController: AlertController
 | 
	
		
			
				|  |  |    ){
 | 
	
		
			
				|  |  |      this.initParse();
 | 
	
		
			
				|  |  |      this.initAuth();
 | 
	
		
			
				|  |  | +    this.initFmodeApi();
 | 
	
		
			
				|  |  | +    this.registerGlobalAlertEvents();
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    // 初始化Parse配置
 | 
	
	
		
			
				|  | @@ -43,4 +47,134 @@ export class App {
 | 
	
		
			
				|  |  |        console.error('❌ 企业微信认证初始化失败:', error);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // 注册全局 Alert 事件(信息提示、确认、输入)
 | 
	
		
			
				|  |  | +  private registerGlobalAlertEvents(): void {
 | 
	
		
			
				|  |  | +    window.addEventListener('globalAlert', (e: Event) => {
 | 
	
		
			
				|  |  | +      const evt = e as CustomEvent<any>;
 | 
	
		
			
				|  |  | +      this.handleGlobalAlert(evt.detail);
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +    window.addEventListener('globalPrompt', (e: Event) => {
 | 
	
		
			
				|  |  | +      const evt = e as CustomEvent<any>;
 | 
	
		
			
				|  |  | +      const detail = evt.detail || {};
 | 
	
		
			
				|  |  | +      this.presentPrompt(detail);
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // 挂载到 window.fmode API,支持直接函数调用
 | 
	
		
			
				|  |  | +  private initFmodeApi(): void {
 | 
	
		
			
				|  |  | +    try {
 | 
	
		
			
				|  |  | +      const fmode: any = (window as any).fmode || {};
 | 
	
		
			
				|  |  | +      fmode.alert = (detail: any) => this.handleGlobalAlert(detail);
 | 
	
		
			
				|  |  | +      // 支持两种用法:
 | 
	
		
			
				|  |  | +      // 1) 对象用法:window.fmode.input({ header, message, inputs, buttons, callback }) 保留原功能
 | 
	
		
			
				|  |  | +      // 2) 字符串简化用法:window.fmode.input('描述', '默认值'),行为与 prompt() 一致,返回输入值或 null
 | 
	
		
			
				|  |  | +      fmode.input = (detailOrMessage: any, defaultValue?: string) => {
 | 
	
		
			
				|  |  | +        if (typeof detailOrMessage === 'string') {
 | 
	
		
			
				|  |  | +          return this.presentPromptSimple(detailOrMessage, defaultValue);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        return this.presentPrompt(detailOrMessage);
 | 
	
		
			
				|  |  | +      };
 | 
	
		
			
				|  |  | +      (window as any).fmode = fmode;
 | 
	
		
			
				|  |  | +      console.log('✅ window.fmode API 已挂载');
 | 
	
		
			
				|  |  | +    } catch (error) {
 | 
	
		
			
				|  |  | +      console.error('❌ 挂载 window.fmode 失败:', error);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // 处理全局信息提示/确认
 | 
	
		
			
				|  |  | +  private async handleGlobalAlert(detail: any): Promise<any> {
 | 
	
		
			
				|  |  | +    const header = detail?.header ?? '提示';
 | 
	
		
			
				|  |  | +    const subHeader = detail?.subHeader ?? undefined;
 | 
	
		
			
				|  |  | +    const message = detail?.message ?? '';
 | 
	
		
			
				|  |  | +    const buttons = detail?.buttons ?? [
 | 
	
		
			
				|  |  | +      { text: '确定', role: 'confirm' }
 | 
	
		
			
				|  |  | +    ];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    const alert = await this.alertController.create({
 | 
	
		
			
				|  |  | +      header,
 | 
	
		
			
				|  |  | +      subHeader,
 | 
	
		
			
				|  |  | +      message,
 | 
	
		
			
				|  |  | +      buttons
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +    await alert.present();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    const result = await alert.onDidDismiss();
 | 
	
		
			
				|  |  | +    this.returnResult(detail, result);
 | 
	
		
			
				|  |  | +    return result;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // 全局输入弹窗
 | 
	
		
			
				|  |  | +  private async presentPrompt(detail: any): Promise<any> {
 | 
	
		
			
				|  |  | +    const header = detail?.header ?? '请输入';
 | 
	
		
			
				|  |  | +    const subHeader = detail?.subHeader ?? undefined;
 | 
	
		
			
				|  |  | +    const message = detail?.message ?? '';
 | 
	
		
			
				|  |  | +    const inputs = detail?.inputs ?? [
 | 
	
		
			
				|  |  | +      { name: 'value', type: 'text', placeholder: '请输入内容' }
 | 
	
		
			
				|  |  | +    ];
 | 
	
		
			
				|  |  | +    const buttons = detail?.buttons ?? [
 | 
	
		
			
				|  |  | +      { text: '取消', role: 'cancel' },
 | 
	
		
			
				|  |  | +      { text: '确定', role: 'confirm' }
 | 
	
		
			
				|  |  | +    ];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    const alert = await this.alertController.create({
 | 
	
		
			
				|  |  | +      header,
 | 
	
		
			
				|  |  | +      subHeader,
 | 
	
		
			
				|  |  | +      message,
 | 
	
		
			
				|  |  | +      inputs,
 | 
	
		
			
				|  |  | +      buttons
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +    await alert.present();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    const result = await alert.onDidDismiss();
 | 
	
		
			
				|  |  | +    this.returnResult(detail, result);
 | 
	
		
			
				|  |  | +    return result;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // 字符串简化用法:行为与原生 prompt() 相同,返回输入字符串或 null
 | 
	
		
			
				|  |  | +  private async presentPromptSimple(message: string, defaultValue?: string): Promise<string | null> {
 | 
	
		
			
				|  |  | +    const alert = await this.alertController.create({
 | 
	
		
			
				|  |  | +      header: '请输入',
 | 
	
		
			
				|  |  | +      message,
 | 
	
		
			
				|  |  | +      inputs: [
 | 
	
		
			
				|  |  | +        { name: 'value', type: 'text', placeholder: '请输入内容', value: defaultValue ?? '' }
 | 
	
		
			
				|  |  | +      ],
 | 
	
		
			
				|  |  | +      buttons: [
 | 
	
		
			
				|  |  | +        { text: '取消', role: 'cancel' },
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +          text: '确定',
 | 
	
		
			
				|  |  | +          role: 'confirm',
 | 
	
		
			
				|  |  | +          handler: (value: any) => {
 | 
	
		
			
				|  |  | +            // 主动传递输入值作为 data,确保 onDidDismiss() 可获取字符串
 | 
	
		
			
				|  |  | +            const v = value?.value ?? '';
 | 
	
		
			
				|  |  | +            alert.dismiss(v, 'confirm');
 | 
	
		
			
				|  |  | +            return false; // 阻止默认关闭,使用我们主动 dismiss
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      ]
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +    await alert.present();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    const result = await alert.onDidDismiss();
 | 
	
		
			
				|  |  | +    if (result.role === 'confirm') {
 | 
	
		
			
				|  |  | +      return (result.data as string) ?? '';
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    return null;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // 结果返回:优先调用回调,其次派发结果事件
 | 
	
		
			
				|  |  | +  private returnResult(detail: any, result: any): void {
 | 
	
		
			
				|  |  | +    try {
 | 
	
		
			
				|  |  | +      if (typeof detail?.callback === 'function') {
 | 
	
		
			
				|  |  | +        detail.callback(result);
 | 
	
		
			
				|  |  | +        return;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      const requestId = detail?.requestId ?? undefined;
 | 
	
		
			
				|  |  | +      window.dispatchEvent(new CustomEvent('globalAlert:result', {
 | 
	
		
			
				|  |  | +        detail: { requestId, result }
 | 
	
		
			
				|  |  | +      }));
 | 
	
		
			
				|  |  | +    } catch (err) {
 | 
	
		
			
				|  |  | +      console.error('全局Alert结果处理异常:', err);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  |  }
 |