基于企业微信的设计师项目全流程管理系统,支持从客户咨询、订单分配、需求确认、交付执行到售后归档的完整生命周期管理。
| 角色 | Profile.role | 职责 | 主要权限 | 
|---|---|---|---|
| 客服 | 客服 | 接单、跟进、售后 | 创建项目、查看客户完整信息、发起结算 | 
| 组员 | 组员 | 设计执行 | 上传交付物、自查质量、查看部分客户信息 | 
| 组长 | 组长 | 审核、分配、质检 | 分配任务、审核交付物、提出Issue | 
| 财务 | 财务 | 审核报价、确认收款 | 审核报价、确认付款凭证 | 
| 管理员 | 管理员 | 系统管理 | 全部权限 | 
| 功能模块 | 客服 | 组员 | 组长 | 财务 | 
|---|---|---|---|---|
| 查看客户手机号 | ✅ | ❌ | ✅ | ❌ | 
| 创建项目 | ✅ | ❌ | ✅ | ❌ | 
| 分配设计师 | ✅ | ❌ | ✅ | ❌ | 
| 上传参考图 | ✅ | ✅ | ✅ | ❌ | 
| AI生成方案 | ✅ | ✅ | ✅ | ❌ | 
| 上传交付物 | ❌ | ✅ | ✅ | ❌ | 
| 审核交付物 | ❌ | ❌ | ✅ | ❌ | 
| 提出Issue | ❌ | ❌ | ✅ | ❌ | 
| 创建报价 | ✅ | ❌ | ✅ | ❌ | 
| 审核报价 | ❌ | ❌ | ❌ | ✅ | 
| 发起结算 | ✅ | ❌ | ✅ | ❌ | 
| 确认收款 | ❌ | ❌ | ❌ | ✅ | 
| 项目归档 | ✅ | ❌ | ✅ | ❌ | 
企业微信会话
    ↓
项目预加载页 (WxworkSDK获取上下文)
    ↓
    ├─ 群聊入口 → 项目详情组件
    └─ 联系人入口 → 客户画像组件
src/modules/project/
├── pages/
│   ├── project-loader/              # 项目预加载页面
│   │   ├── project-loader.component.ts
│   │   └── project-loader.component.html
│   ├── contact/            # 客户画像页面
│   │   ├── contact.component.ts
│   │   └── contact.component.html
│   └── project-detail/              # 项目详情页面
│       ├── project-detail.component.ts
│       ├── project-detail.component.html
│       └── components/
│           ├── stage-order/         # 订单分配阶段
│           ├── stage-requirements/  # 确认需求阶段
│           ├── stage-delivery/      # 交付执行阶段
│           └── stage-aftercare/     # 售后归档阶段
├── components/
│   ├── customer-info/               # 客户信息卡片
│   ├── reference-image-uploader/    # 参考图上传
│   ├── ai-solution-generator/       # AI方案生成
│   ├── deliverable-uploader/        # 交付物上传
│   ├── quality-checklist/           # 质量自查清单
│   └── settlement-manager/          # 结算管理
└── services/
    ├── project-wxwork.service.ts    # 企微项目服务
    ├── ai-solution.service.ts       # AI方案生成服务
    └── deliverable.service.ts       # 交付物服务
// app.routes.ts
{
  path: 'wxwork/:cid',
  canActivate: [WxworkAuthGuard],
  children: [
    // 项目预加载页
    {
      path: 'project-loader',
      component: ProjectLoaderComponent
    },
    // 客户画像
    {
      path: 'customer/:contactId',
      component: CustomerProfileComponent
    },
    // 项目详情(支持调试)
    {
      path: 'project/:projectId',
      component: ProjectDetailComponent,
      children: [
        { path: '', redirectTo: 'order', pathMatch: 'full' },
        { path: 'order', component: StageOrderComponent },
        { path: 'requirements', component: StageRequirementsComponent },
        { path: 'delivery', component: StageDeliveryComponent },
        { path: 'aftercare', component: StageAftercareComponent }
      ]
    }
  ]
}
从企业微信会话进入时的首屏页面,负责获取企微上下文、识别用户身份、加载或创建项目。
加载页面
    ↓
显示骨架屏
    ↓
获取企微上下文 (WxworkSDK.getCurrentChatObject())
    ├─ 群聊场景 → GroupChat
    └─ 联系人场景 → ContactInfo
    ↓
获取当前用户 (WxworkSDK.getCurrentUser())
    ↓ 得到 Profile (role决定权限)
    ↓
根据场景加载数据
    ├─ 群聊 → 查询 GroupChat.project
    │   ├─ 有项目 → 跳转项目详情
    │   └─ 无项目 → 显示创建项目引导
    └─ 联系人 → 跳转客户画像
// project-loader.component.ts
export class ProjectLoaderComponent implements OnInit {
  loading = true;
  currentUser: FmodeObject | null = null; // Profile
  groupChat: FmodeObject | null = null;   // GroupChat
  contact: FmodeObject | null = null;     // ContactInfo
  project: FmodeObject | null = null;     // Project
  async ngOnInit() {
    const cid = this.route.snapshot.paramMap.get('cid')!;
    const wxwork = new WxworkSDK({ cid, appId: 'crm' });
    try {
      // 1. 获取企微上下文
      const { GroupChat, Contact } = await wxwork.getCurrentChatObject();
      this.groupChat = GroupChat;
      this.contact = Contact;
      // 2. 获取当前用户
      this.currentUser = await wxwork.getCurrentUser();
      // 3. 根据场景处理
      if (this.groupChat) {
        await this.handleGroupChatScene();
      } else if (this.contact) {
        await this.handleContactScene();
      }
    } catch (error) {
      console.error('加载失败:', error);
    } finally {
      this.loading = false;
    }
  }
  async handleGroupChatScene() {
    // 查询群聊关联的项目
    const projectPointer = this.groupChat!.get('project');
    if (projectPointer) {
      // 有项目,跳转详情
      this.router.navigate(['/wxwork', this.cid, 'project', projectPointer.id]);
    } else {
      // 无项目,显示创建引导
      this.showCreateProjectGuide();
    }
  }
  async handleContactScene() {
    // 跳转客户画像
    this.router.navigate(['/wxwork', this.cid, 'customer', this.contact!.id]);
  }
  showCreateProjectGuide() {
    // 显示骨架屏 + 创建项目表单
    this.showGuide = true;
    this.defaultProjectName = this.groupChat!.get('name');
  }
  async createProject(projectName: string) {
    const Project = Parse.Object.extend('Project');
    const project = new Project();
    project.set('title', projectName);
    project.set('company', this.currentUser!.get('company'));
    project.set('status', '待分配');
    project.set('currentStage', '订单分配');
    await project.save();
    // 关联群聊
    this.groupChat!.set('project', project.toPointer());
    await this.groupChat!.save();
    // 跳转项目详情
    this.router.navigate(['/wxwork', this.cid, 'project', project.id]);
  }
}
从联系人侧边栏进入,展示客户的完整画像信息,包括基础信息、所在群聊、项目列表、跟进记录等。
interface CustomerProfile {
  basic: {
    name: string;
    mobile?: string;      // 仅客服/组长可见
    wechat?: string;      // 仅客服/组长可见
    avatar: string;
    source: string;       // 来源渠道
    tags: string[];       // 客户标签
  };
  groups: GroupChatInfo[];  // 所在群聊
  projects: ProjectInfo[];  // 相关项目
  followUp: FollowUpRecord[]; // 跟进记录
  preferences: {
    style: string[];
    budget: { min: number; max: number };
    colorAtmosphere: string;
  };
}
┌────────────────────────────┐
│  头像 + 姓名 + 来源标签      │
├────────────────────────────┤
│  基础信息卡片               │
│  - 手机号(权限控制)       │
│  - 微信号(权限控制)       │
│  - 客户类型                 │
├────────────────────────────┤
│  客户画像                   │
│  - 风格偏好                 │
│  - 预算范围                 │
│  - 色彩氛围                 │
├────────────────────────────┤
│  所在群聊(可点击跳转)     │
│  ┌──────────┐ ┌──────────┐│
│  │ 群1 - 项目A│ │ 群2 - 项目B││
│  └──────────┘ └──────────┘│
├────────────────────────────┤
│  历史项目列表               │
│  - 项目名称 + 状态 + 进度   │
├────────────────────────────┤
│  跟进记录时间线             │
│  - 咨询时间                 │
│  - 报价时间                 │
│  - 签约时间                 │
└────────────────────────────┘
WxworkSDK.openChat(chatId) 跳转四大阶段流程:
订单分配 → 确认需求 → 交付执行 → 售后归档
页面头部导航:
手机端布局:
主要操作人: 客服
核心功能:
填写项目基础信息
创建报价清单
interface QuotationBreakdown {
 spaces: SpaceQuotation[];  // 按空间报价
 totalAmount: number;
}
interface SpaceQuotation {
 space: string;     // 客厅、主卧、次卧等
 area: number;      // 面积
 items: QuotationItem[];
 subtotal: number;
}
interface QuotationItem {
 process: 'modeling' | 'softDecor' | 'rendering' | 'postProcess';
 quantity: number;  // 数量(如渲染张数)
 unitPrice: number;
 amount: number;
}
分配设计师
报价审核流程
页面布局:
┌────────────────────────────┐
│  客户信息卡片               │
│  - 姓名 + 来源 + 偏好标签   │
├────────────────────────────┤
│  项目基础信息表单           │
│  - 项目名称                 │
│  - 项目类型                 │
│  - 截止时间                 │
├────────────────────────────┤
│  报价清单编辑器             │
│  ┌──── 客厅 (40㎡) ────┐  │
│  │ 建模: 1套 x 2000    │  │
│  │ 软装: 1套 x 1500    │  │
│  │ 渲染: 3张 x 800     │  │
│  │ 后期: 3张 x 200     │  │
│  │ 小计: 6500元        │  │
│  └────────────────────┘  │
│  [+ 添加空间]            │
│  总计: 18,000元          │
├────────────────────────────┤
│  设计师分配                │
│  [选择主设计师]            │
│  当前负载: 5/8个项目        │
├────────────────────────────┤
│  [提交审核]                │
└────────────────────────────┘
数据存储:
// Product表 - 按空间+工序存储报价项
const product = new Parse.Object('Product');
product.set('project', projectPointer);
product.set('space', '客厅');
product.set('processType', 'modeling');
product.set('quotation', {
  price: 2000,
  quantity: 1,
  status: '待审核'
});
主要操作人: 组长、组员
核心功能:
2.1 上传参考图
点击图片可查看大图和色彩分析
// ProjectFile表
const refImage = new Parse.Object('ProjectFile');
refImage.set('project', projectPointer);
refImage.set('fileType', 'reference');
refImage.set('fileUrl', imageUrl);
refImage.set('fileName', 'living-room-ref-01.jpg');
refImage.set('stage', '确认需求');
refImage.set('data', {
description: '现代简约风格客厅,暖色调为主',
colorAnalysis: {
primaryHue: 30,
saturation: 45,
temperature: '暖色调'
}
});
2.2 色彩分析弹窗
2.3 上传CAD图纸
.dwg .dxf 格式2.4 其他需求录入
2.5 AI生成方案
触发条件:
调用流程:
// ai-solution.service.ts
async generateSolution(projectId: string): Promise<string> {
  // 1. 收集数据
  const requirement = await this.loadRequirement(projectId);
  const refImages = await this.loadReferenceImages(projectId);
  const colorAnalysis = await this.analyzeColors(refImages);
  // 2. 构建 Prompt
  const prompt = this.buildPrompt({
    requirement,
    colorAnalysis,
    spaces: requirement.get('spaces')
  });
  // 3. 调用大模型
  const response = await this.callLLM(prompt);
  // 4. 保存方案
  requirement.set('data', {
    ...requirement.get('data'),
    aiSolution: {
      content: response,
      generatedAt: new Date()
    }
  });
  await requirement.save();
  return response;
}
Prompt 模板:
你是一位资深的室内设计师,请根据以下信息生成详细的设计方案分析:
## 项目信息
- 空间类型:{spaces}
- 总面积:{totalArea}㎡
- 风格偏好:{stylePreferences}
## 色彩分析
- 主色调:{primaryHue}°(色相)
- 饱和度:{saturation}%
- 色温:{temperature}
- 色彩分布:{colorDistribution}
## 客户需求
{requirements}
## 任务
请生成以下内容:
1. 整体设计风格定位(200字)
2. 色彩方案建议(每个空间)
3. 材质搭配建议
4. 家具形体建议
5. 灯光布局建议
6. 注意事项和禁忌
请以Markdown格式输出,结构清晰,便于阅读。
方案展示:
页面布局:
┌────────────────────────────┐
│  参考图网格                 │
│  ┌───┐ ┌───┐ ┌───┐        │
│  │图1│ │图2│ │图3│ [+上传]│
│  └───┘ └───┘ └───┘        │
├────────────────────────────┤
│  CAD图纸列表                │
│  📄 原始户型图.dwg          │
│  📄 水电布局图.dwg          │
│  [+ 上传CAD]               │
├────────────────────────────┤
│  需求清单                   │
│  ✓ 需要大储物空间           │
│  ✓ 智能家电                 │
│  [+ 添加需求]              │
├────────────────────────────┤
│  [🤖 AI生成设计方案]        │
├────────────────────────────┤
│  AI方案展示区(折叠)       │
│  【已生成】                │
│  > 查看完整方案            │
└────────────────────────────┘
主要操作人: 组员(上传)、组长(审核)
核心功能:
3.1 交付物上传
按报价清单的空间和工序组织:
客厅
  ├─ 白模 (modeling)
  │   └─ [上传图片] 自查清单 状态
  ├─ 软装 (softDecor)
  │   └─ [上传图片] 自查清单 状态
  ├─ 渲染 (rendering)
  │   └─ [上传图片] 渲染进度 状态
  └─ 后期 (postProcess)
      └─ [上传图片] 自查清单 状态
主卧
  ├─ ...
3.2 质量自查清单
每个交付物都有对应的自查项(ProductCheck):
// 建模自查项
const modelChecks = [
  '尺寸准确性',
  '材质贴图正确',
  '模型结构合理',
  '无破面和漏洞'
];
// 渲染自查项
const renderChecks = [
  '光影自然',
  '色彩还原准确',
  '分辨率符合要求',
  '无明显瑕疵'
];
组员上传后需逐项打勾确认:
const check = new Parse.Object('ProductCheck');
check.set('project', projectPointer);
check.set('checkType', 'model');
check.set('checkedBy', currentUserPointer);
check.set('isPassed', true);
check.set('items', [
  { name: '尺寸准确性', isPassed: true, notes: '' },
  { name: '材质贴图正确', isPassed: true, notes: '' },
  { name: '模型结构合理', isPassed: false, notes: '需要调整沙发位置' }
]);
3.3 组长审核与Issue
组长可以对交付物提出Issue(ProjectIssue):
const issue = new Parse.Object('ProjectIssue');
issue.set('project', projectPointer);
issue.set('reportedBy', leaderProfilePointer);
issue.set('exceptionType', 'quality');
issue.set('severity', 'medium');
issue.set('description', '客厅渲染图色调偏冷,需要调整为暖色调');
issue.set('status', '待处理');
issue.set('data', {
  relatedDeliverable: productId,  // 关联的Product
  relatedStage: '渲染',
  space: '客厅'
});
组员在页面上会看到醒目的Issue提示,点击查看详情并处理。
3.4 发起交付
当组员完成所有交付物上传并自查通过后,可点击"发起交付"按钮:
同时发起尾款收款请求
async initiateDelivery() {
// 1. 检查完成度
const deliveryRate = await this.checkDeliveryCompleteness();
if (deliveryRate < 100) {
alert('还有交付物未完成,请检查');
return;
}
// 2. 更新项目阶段
project.set('currentStage', '尾款结算');
await project.save();
// 3. 发送企微消息
await this.wecorp.appchat.sendText(
chatId,
`【项目交付通知】\n${project.get('title')} 已完成全部设计工作,请查收成果。\n如有修改意见请及时反馈。`
);
// 4. 创建尾款结算记录
const settlement = new Parse.Object('ProjectSettlement');
settlement.set('project', projectPointer);
settlement.set('stage', '尾款');
settlement.set('amount', finalAmount);
settlement.set('status', '待结算');
settlement.set('dueDate', new Date(Date.now() + 7 * 24 * 60 * 60 * 1000)); // 7天后
await settlement.save();
}
页面布局:
┌────────────────────────────┐
│  交付进度总览               │
│  ████████░░ 80%             │
│  已完成 12/15 项            │
├────────────────────────────┤
│  空间列表(可折叠)         │
│  ▼ 客厅                     │
│    ├─ 白模 ✓               │
│    ├─ 软装 ✓               │
│    ├─ 渲染 🔄 (进行中)     │
│    └─ 后期 ⏸ (待开始)      │
│  ▶ 主卧                     │
│  ▶ 次卧                     │
├────────────────────────────┤
│  当前工作:客厅渲染         │
│  ┌────────────────────┐   │
│  │ [上传图片]          │   │
│  │ 已上传: 3张          │   │
│  │ 渲染进度: 60%        │   │
│  └────────────────────┘   │
│  质量自查清单              │
│  ☑ 光影自然                │
│  ☑ 色彩准确                │
│  ☐ 分辨率符合要求          │
├────────────────────────────┤
│  ⚠️ Issue提醒 (2个待处理)  │
│  • 客厅渲染色调需调整      │
│  • 主卧软装需补充细节      │
├────────────────────────────┤
│  [发起交付](灰色/可点击)  │
└────────────────────────────┘
主要操作人: 客服
核心功能:
4.1 尾款管理
4.2 客户评价
评价维度:设计质量、服务态度、交付时效
const feedback = new Parse.Object('ProjectFeedback');
feedback.set('project', projectPointer);
feedback.set('customer', customerPointer);
feedback.set('stage', '客户评价');
feedback.set('feedbackType', 'praise');
feedback.set('rating', 5);
feedback.set('content', '设计师非常专业,效果图很满意!');
feedback.set('status', '已完成');
4.3 项目复盘
4.4 项目归档
GroupChat.project 设为 null(解除关联)项目进入历史项目列表
async archiveProject() {
// 1. 检查是否可归档
if (!this.checkCanArchive()) {
alert('请先完成尾款结算和客户评价');
return;
}
// 2. 更新项目状态
project.set('status', '已完成');
project.set('data', {
...project.get('data'),
archivedAt: new Date(),
archivedBy: currentUserPointer.id
});
await project.save();
// 3. 解除群聊关联
groupChat.set('project', null);
await groupChat.save();
// 4. 发送归档通知
await this.wecorp.appchat.sendText(
chatId,
`【项目归档通知】\n${project.get('title')} 已完成归档,感谢您的信任与支持!`
);
// 5. 返回工作台
this.router.navigate(['/wxwork', this.cid, 'project-loader']);
}
页面布局:
┌────────────────────────────┐
│  尾款信息                   │
│  应收金额: ¥5,400          │
│  截止日期: 2025-10-20      │
│  状态: 已收款 ✓             │
├────────────────────────────┤
│  付款凭证                   │
│  ┌────────────────────┐   │
│  │ [查看凭证图片]      │   │
│  │ 识别金额: 5400元     │   │
│  │ 付款时间: 2025-10-18│   │
│  └────────────────────┘   │
├────────────────────────────┤
│  客户评价                   │
│  ⭐⭐⭐⭐⭐ 5.0分          │
│  "设计师非常专业,效果图很│
│   满意!交付及时。"        │
├────────────────────────────┤
│  项目复盘                   │
│  [查看完整复盘报告]        │
│  • 项目总评分: 92分         │
│  • 交付准时率: 100%        │
│  • 客户满意度: 5.0星       │
├────────────────────────────┤
│  [📦 归档项目]              │
└────────────────────────────┘
获取上下文:
// 从企微会话获取群聊或联系人
const { GroupChat, Contact, currentChat } = await wxwork.getCurrentChatObject();
if (GroupChat) {
  // 群聊场景
  const project = GroupChat.get('project');
} else if (Contact) {
  // 联系人场景
  const name = Contact.get('name');
}
获取当前用户:
// 获取当前登录的员工信息
const profile = await wxwork.getCurrentUser();
const role = profile.get('roleName'); // 客服/组员/组长
发送企微消息:
await wecorp.appchat.sendText(chatId, '消息内容');
await wecorp.appchat.sendImage(chatId, imageUrl);
创建记录:
const Project = Parse.Object.extend('Project');
const project = new Project();
project.set('title', '项目名称');
project.set('company', companyPointer);
await project.save();
查询记录:
const query = new Parse.Query('Project');
query.equalTo('company', companyId);
query.equalTo('status', '进行中');
query.include('customer', 'assignee');
const projects = await query.find();
更新记录:
project.set('currentStage', '确认需求');
await project.save();
参考示例代码 /home/ryan/workspace/nova/nova-admin/projects/ai-k12-daofa/src/modules/daofa/search/search.component.ts
import { HttpClient } from '@angular/common/http';
export class AiSolutionService {
  constructor(private http: HttpClient) {}
  async generateSolution(prompt: string): Promise<string> {
    const response = await this.http.post<any>('https://api.example.com/v1/chat/completions', {
      model: 'qwen-plus',
      messages: [
        { role: 'system', content: '你是一位资深室内设计师' },
        { role: 'user', content: prompt }
      ],
      temperature: 0.7,
      max_tokens: 2000
    }).toPromise();
    return response.choices[0].message.content;
  }
}
Ionic组件:
<ion-header>
  <ion-toolbar>
    <ion-title>项目详情</ion-title>
  </ion-toolbar>
</ion-header>
<ion-content>
  <ion-card>
    <ion-card-header>
      <ion-card-title>客户信息</ion-card-title>
    </ion-card-header>
    <ion-card-content>
      ...
    </ion-card-content>
  </ion-card>
</ion-content>
响应式布局:
.project-detail {
  @media (max-width: 768px) {
    // 手机端样式
    .header-nav {
      flex-direction: column;
    }
  }
}
客服在群聊打开工具
    ↓
项目预加载页
    ↓
检测无项目 → 显示创建引导
    ↓
填写项目名称 → 创建Project
    ↓
关联GroupChat.project
    ↓
跳转项目详情 - 订单分配阶段
组员上传参考图 → 保存到ProjectFile
    ↓
点击参考图 → 色彩分析 → 保存到ProjectRequirement
    ↓
填写需求清单
    ↓
点击"AI生成方案" → 调用大模型
    ↓
生成方案 → 保存到ProjectRequirement.data.aiSolution
    ↓
方案展示 → Markdown渲染
组员上传交付物 → 保存到Product
    ↓
填写质量自查清单 → 保存到ProductCheck
    ↓
组长审核 → 提出Issue(如有问题)
    ↓
组员修改 → 重新上传
    ↓
所有交付物完成 → 点击"发起交付"
    ↓
更新项目阶段 → 发送企微通知 → 创建尾款结算
| 测试场景 | 前置条件 | 操作步骤 | 预期结果 | 
|---|---|---|---|
| 从群聊创建项目 | 群聊无关联项目 | 打开工具 → 填写项目名 → 点击创建 | 项目创建成功,跳转详情页 | 
| 重复创建检测 | 群聊已有项目 | 打开工具 | 直接跳转到现有项目详情 | 
| 权限检查 | 非客服角色 | 打开工具 → 尝试创建项目 | 提示"无权限" | 
| 测试场景 | 前置条件 | 操作步骤 | 预期结果 | 
|---|---|---|---|
| 首次生成方案 | 已上传参考图和需求 | 点击"AI生成方案" | 调用大模型,生成方案并展示 | 
| 重新生成 | 已有方案 | 更新需求 → 重新生成 | 生成新方案,保留历史版本 | 
| 缺少数据 | 未上传参考图 | 点击"AI生成方案" | 提示"请先上传参考图" | 
| 测试场景 | 前置条件 | 操作步骤 | 预期结果 | 
|---|---|---|---|
| 上传白模图 | 在交付执行阶段 | 选择文件 → 上传 | 图片保存成功,显示在列表 | 
| 质量自查 | 已上传交付物 | 勾选自查项 → 保存 | 自查记录保存成功 | 
| 组长提Issue | 组长角色 | 查看交付物 → 提出问题 | Issue创建成功,组员可见 | 
项目状态 (Project.status):
待分配: 新建项目,等待分配设计师进行中: 设计中已暂停: 客户要求暂停已延期: 超期已完成: 已归档已取消: 项目取消项目阶段 (Project.currentStage):
订单分配确认需求方案确认(并列任务)
建模软装渲染后期尾款结算客户评价投诉处理审核状态 (reviewStatus):
pending: 待审核approved: 已通过rejected: 已驳回revision_required: 需要修改// 权限检查辅助函数
function hasPermission(role: string, action: string): boolean {
  const permissions = {
    '客服': ['createProject', 'viewCustomerPhone', 'createQuotation', 'initiateSettlement'],
    '组员': ['uploadDeliverable', 'qualityCheck', 'uploadReference'],
    '组长': ['assignDesigner', 'reviewDeliverable', 'createIssue', 'viewCustomerPhone'],
    '财务': ['approveQuotation', 'confirmPayment']
  };
  return permissions[role]?.includes(action) || false;
}
// 使用示例
if (!hasPermission(currentUser.get('roleName'), 'createProject')) {
  alert('您没有权限创建项目');
  return;
}
文档结束
如有疑问,请联系产品团队。