# 动态数据对接和企业微信认证集成文档 ## 概述 本文档说明了如何在 yss-project 中集成企业微信认证 (WxworkAuthGuard) 和动态数据服务 (FmodeParse)。 ## 已完成的功能 ### 1. 企业微信认证集成 #### 路由守卫配置 已在 `src/app/app.routes.ts` 中为所有主要路由添加了 `WxworkAuthGuard`: ```typescript import { WxworkAuthGuard } from 'fmode-ng/social'; // 客服路由 { path: 'customer-service', canActivate: [WxworkAuthGuard], children: [...] } // 设计师路由 { path: 'designer', canActivate: [WxworkAuthGuard], children: [...] } // 组长路由 { path: 'team-leader', canActivate: [WxworkAuthGuard], children: [...] } // 财务路由 { path: 'finance', canActivate: [WxworkAuthGuard], children: [...] } // 人事路由 { path: 'hr', canActivate: [WxworkAuthGuard], children: [...] } // 管理员路由 { path: 'admin', canActivate: [WxworkAuthGuard], children: [...] } ``` #### 组件级认证 已在主要页面组件中集成了 `WxworkAuth` 类: **管理员仪表板** (`src/app/pages/admin/dashboard/dashboard.ts`) ```typescript import { WxworkAuth, FmodeQuery, FmodeObject, FmodeUser } from 'fmode-ng/core'; private initAuth(): void { this.wxAuth = new WxworkAuth({ cid: 'cDL6R1hgSi' // 公司帐套ID }); } private async authenticateAndLoadData(): Promise { const { user } = await this.wxAuth.authenticateAndLogin(); if (user) { console.log('✅ 管理员登录成功:', user.get('username')); await this.loadDashboardData(); } } ``` **客服仪表板** (`src/app/pages/customer-service/dashboard/dashboard.ts`) ```typescript // 同样的认证模式,加载咨询统计数据 private async loadConsultationStats(): Promise { const consultationQuery = new FmodeQuery('Consultation'); consultationQuery.equalTo('status', 'new'); const newConsultations = await consultationQuery.count(); this.stats.newConsultations.set(newConsultations); } ``` **设计师仪表板** (`src/app/pages/designer/dashboard/dashboard.ts`) ```typescript // 同样的认证模式,加载任务数据 ``` ### 2. FmodeParse 初始化 已在 `src/app/app.ts` 中初始化了 FmodeParse: ```typescript import { FmodeParse } from 'fmode-ng/core'; private initParse(): void { try { const Parse = FmodeParse.with("nova"); console.log('✅ FmodeParse 初始化成功'); } catch (error) { console.error('❌ FmodeParse 初始化失败:', error); } } ``` ### 3. 动态数据对接 #### 管理员仪表板数据源 **项目统计** ```typescript private async loadProjectStats(): Promise { const projectQuery = new FmodeQuery('Project'); // 总项目数 const totalProjects = await projectQuery.count(); this.stats.totalProjects.set(totalProjects); // 进行中项目数 projectQuery.equalTo('status', '进行中'); const activeProjects = await projectQuery.count(); this.stats.activeProjects.set(activeProjects); } ``` **用户统计** ```typescript private async loadUserStats(): Promise { // 设计师统计 const designerQuery = new FmodeQuery('Profile'); designerQuery.equalTo('role', 'designer'); const designers = await designerQuery.count(); this.stats.totalDesigners.set(designers); } ``` **收入统计** ```typescript private async loadRevenueStats(): Promise { const orderQuery = new FmodeQuery('Order'); orderQuery.equalTo('status', 'paid'); const orders = await orderQuery.find(); let totalRevenue = 0; for (const order of orders) { const amount = order.get('amount') || 0; totalRevenue += amount; } this.stats.totalRevenue.set(totalRevenue); } ``` #### 客服仪表板数据源 **咨询统计** ```typescript private async loadConsultationStats(): Promise { // 新咨询数 const consultationQuery = new FmodeQuery('Consultation'); consultationQuery.equalTo('status', 'new'); consultationQuery.greaterThanOrEqualTo('createdAt', new Date(new Date().setHours(0,0,0,0))); const newConsultations = await consultationQuery.count(); this.stats.newConsultations.set(newConsultations); } ``` ### 4. NovaStorage 上传组件 #### 上传组件 (`src/app/shared/components/upload-component/`) 直接使用 `NovaStorage.withCid(cid).upload()` 方法,无需额外服务层。 **功能特性:** - 拖拽上传支持 - 多文件上传 - 文件类型和大小验证 - 上传进度显示 - 预览功能 - 错误处理 - 自动文件路径生成 **核心实现:** ```typescript import { NovaStorage, NovaFile } from 'fmode-ng/core'; // 初始化存储服务 private async initStorage(): Promise { const cid = localStorage.getItem('company') || 'cDL6R1hgSi'; this.storage = await NovaStorage.withCid(cid); } // 上传文件 const uploaded: NovaFile = await this.storage.upload(file, { prefixKey: 'project/pid/', // 可选的路径前缀 onProgress: (p) => console.log('进度:', p.total.percent), }); ``` **使用示例:** ```typescript import { UploadComponent, UploadResult } from './shared/components/upload-component/upload.component'; @Component({ standalone: true, imports: [UploadComponent] }) export class MyComponent { onUploadComplete(results: UploadResult[]) { results.forEach(result => { if (result.success) { console.log('上传成功:', result.file?.url); // 保存文件信息到数据库 this.saveFileInfo(result.file); } }); } private async saveFileInfo(file: NovaFile) { // 保存 key, url, name, type, size, metadata, md5 等信息 console.log('文件信息:', { key: file.key, url: file.url, name: file.name, size: file.size }); } } ``` ```html ``` **示例组件:** `src/app/shared/components/upload-example/` 提供了完整的使用示例和配置选项演示。 ## 数据表结构 ### 主要数据表 1. **Project** - 项目表 - name: 项目名称 - status: 项目状态 (进行中, 已完成, 异常) - owner: 负责人 (Pointer to Profile) - startDate: 开始日期 - endDate: 结束日期 2. **Profile** - 用户档案表 - name: 姓名 - role: 角色 (designer, customer, admin) - level: 级别 (junior, mid, senior) - completedProjects: 完成项目数 - activeProjects: 进行中项目数 3. **Consultation** - 咨询表 - status: 状态 (new, pending_assignment, processing) - customer: 客户 (Pointer to Profile) - createdAt: 创建时间 4. **Order** - 订单表 - status: 订单状态 - amount: 金额 - customer: 客户 (Pointer to Profile) - invoiceNo: 发票号 5. **AfterSales** - 售后表 - status: 状态 - project: 项目 (Pointer to Project) - createdAt: 创建时间 6. **Images** - 图片表 - originalName: 原始文件名 - url: 图片URL - thumbnailUrl: 缩略图URL - size: 文件大小 ## 使用指南 ### 1. 新页面添加认证 对于新页面,按以下步骤添加认证: ```typescript import { WxworkAuth, FmodeQuery, FmodeObject, FmodeUser } from 'fmode-ng/core'; @Component({...}) export class NewPageComponent { private wxAuth: WxworkAuth; private currentUser: FmodeUser | null = null; constructor() { this.initAuth(); } private initAuth(): void { this.wxAuth = new WxworkAuth({ cid: 'cDL6R1hgSi' }); } async ngOnInit(): Promise { await this.authenticateAndLoadData(); } private async authenticateAndLoadData(): Promise { const { user } = await this.wxAuth.authenticateAndLogin(); if (user) { this.currentUser = user; await this.loadData(); } } } ``` ### 2. 数据查询示例 ```typescript // 基本查询 const query = new FmodeQuery('Project'); const projects = await query.find(); // 条件查询 query.equalTo('status', '进行中'); query.greaterThan('createdAt', new Date('2025-01-01')); // 排序 query.descending('createdAt'); // 分页 query.limit(20); query.skip(0); // 计数 const count = await query.count(); // 关联查询 const userQuery = new FmodeQuery('Profile'); userQuery.include('projects'); ``` ### 3. 数据保存示例 ```typescript // 创建新对象 const project = new FmodeObject('Project'); project.set('name', '新项目'); project.set('status', '进行中'); const savedProject = await project.save(); // 更新对象 savedProject.set('status', '已完成'); await savedProject.save(); // 删除对象 await savedProject.destroy(); ``` ### 4. NovaStorage 上传组件使用 ```typescript import { UploadComponent, UploadResult } from '../shared/components/upload-component/upload.component'; @Component({ standalone: true, imports: [UploadComponent] }) export class MyComponent { async onUploadComplete(results: UploadResult[]) { // 处理上传结果 for (const result of results) { if (result.success && result.file) { console.log('上传成功:', result.file.url); // 保存文件信息到数据库 await this.saveFileInfo(result.file); } } } async onUploadError(error: string) { console.error('上传失败:', error); } private async saveFileInfo(file: NovaFile) { // 保存文件信息到 Attachment 表或其他相关表 console.log('保存文件:', file.key, file.url); } } ``` ## 错误处理 所有数据操作都包含错误处理,在API调用失败时会自动降级到模拟数据: ```typescript try { await this.loadDashboardData(); } catch (error) { console.error('❌ 数据加载失败:', error); // 降级到模拟数据 this.loadMockData(); } ``` ## 注意事项 1. **认证配置**: 确保 `cid: 'cDL6R1hgSi'` 在 `WxworkSDK.companyMap` 中有对应配置 2. **数据表名**: 确保后端数据表名与代码中使用的表名一致 3. **权限设置**: 确保企业微信用户有相应的数据访问权限 4. **NovaStorage**: 使用 `NovaStorage.withCid(cid)` 自动初始化,无需手动配置 Provider 5. **文件路径**: 自动生成格式 `storage/company////-` 6. **文件大小**: 默认上传文件大小限制为 10MB,可在组件中自定义 7. **prefixKey**: 通过 `prefixKey` 参数指定文件存储路径前缀,如 `'project/pid/'` ## 后续优化建议 1. **缓存机制**: 为频繁查询的数据添加缓存 2. **实时更新**: 使用 WebSocket 实现数据实时更新 3. **离线支持**: 添加离线数据存储和同步功能 4. **批量操作**: 优化批量数据操作的性能 5. **权限细化**: 根据用户角色实现更细粒度的数据访问控制