浏览代码

Merge branch 'master' of http://git.fmode.cn:3000/nkkj/yss-project

ryanemax 1 天之前
父节点
当前提交
bc1fded3d7

+ 3 - 0
CHANGELOG.md

@@ -3,6 +3,9 @@
 ## 2025-10-24
 ### 项目启动访谈问卷
 
+### 组员管理(项目详情页)
+- 增加删除组员功能,将组员移出项目组
+
 ## 2025-10-23
 
 ### 员工管理(后台)

+ 8 - 8
src/app/app.routes.ts

@@ -1,12 +1,12 @@
 import { Routes } from '@angular/router';
-// import { WxworkAuthGuard } from 'fmode-ng'; // 临时禁用以解决初始化问题
+import { WxworkAuthGuard } from 'fmode-ng/social'; 
 
 export const routes: Routes = [
   // 客服路由
   {
     path: 'customer-service',
     loadComponent: () => import('./pages/customer-service/customer-service-layout/customer-service-layout').then(m => m.CustomerServiceLayout),
-    // canActivate: [WxworkAuthGuard], // 临时禁用
+    canActivate: [WxworkAuthGuard], 
     children: [
       { path: '', redirectTo: 'dashboard', pathMatch: 'full' },
       {
@@ -61,7 +61,7 @@ export const routes: Routes = [
   // 设计师路由
   {
     path: 'designer',
-    // canActivate: [WxworkAuthGuard], // 临时禁用
+    canActivate: [WxworkAuthGuard], 
     children: [
       { path: '', redirectTo: 'dashboard', pathMatch: 'full' },
       {
@@ -85,7 +85,7 @@ export const routes: Routes = [
   // 组长路由
   {
     path: 'team-leader',
-    // canActivate: [WxworkAuthGuard], // 临时禁用用于开发测试
+    canActivate: [WxworkAuthGuard], 
     children: [
       { path: '', redirectTo: 'dashboard', pathMatch: 'full' },
       {
@@ -125,7 +125,7 @@ export const routes: Routes = [
   // 财务路由
   {
     path: 'finance',
-    // canActivate: [WxworkAuthGuard], // 临时禁用
+    canActivate: [WxworkAuthGuard], 
     children: [
       { path: '', redirectTo: 'dashboard', pathMatch: 'full' },
       {
@@ -160,7 +160,7 @@ export const routes: Routes = [
   {
     path: 'hr',
     loadComponent: () => import('./pages/hr/hr-layout/hr-layout').then(m => m.HrLayout),
-    // canActivate: [WxworkAuthGuard], // 临时禁用
+    canActivate: [WxworkAuthGuard], 
     children: [
       {
         path: 'dashboard',
@@ -185,7 +185,7 @@ export const routes: Routes = [
   {
     path: 'admin',
     loadComponent: () => import('./pages/admin/admin-layout/admin-layout').then(m => m.AdminLayout),
-    // canActivate: [WxworkAuthGuard], // 临时禁用
+    canActivate: [WxworkAuthGuard], 
     children: [
       { path: '', redirectTo: 'dashboard', pathMatch: 'full' },
       {
@@ -310,7 +310,7 @@ export const routes: Routes = [
   // 2. 网页端: 通过 contactId/projectId 直接加载,配合 profileId 参数
   {
     path: 'wxwork/:cid',
-    // canActivate: [WxworkAuthGuard], // 可选:使用路由守卫强制认证
+    canActivate: [WxworkAuthGuard],
     children: [
       // 项目预加载页(企微上下文入口)
       {

+ 15 - 0
src/modules/project/components/project-members-modal/project-members-modal.component.html

@@ -180,6 +180,21 @@
                   </button>
                 }
 
+                <!-- 新增:移出项目 -->
+                @if (member.isInProjectTeam) {
+                  <button
+                    class="action-btn remove-btn"
+                    (click)="removeMemberFromProject(member)"
+                    title="移出项目">
+                    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
+                      <circle cx="12" cy="12" r="10"></circle>
+                      <line x1="15" y1="9" x2="9" y2="15"></line>
+                      <line x1="9" y1="9" x2="15" y2="15"></line>
+                    </svg>
+                    <span>移出项目</span>
+                  </button>
+                }
+
                 <div class="status-indicator" [class]="getMemberStatusClass(member)">
                   @if (member.isInProjectTeam && member.isInGroupChat) {
                     <svg viewBox="0 0 24 24" fill="currentColor">

+ 32 - 0
src/modules/project/components/project-members-modal/project-members-modal.component.ts

@@ -315,6 +315,38 @@ export class ProjectMembersModalComponent implements OnInit {
     }
   }
 
+  // 新增:移出项目(软删除 ProjectTeam)
+  async removeMemberFromProject(member: ProjectMember): Promise<void> {
+    if (!member.isInProjectTeam || !member.projectTeamId) {
+      alert('该成员未在项目团队中,无法移出项目');
+      return;
+    }
+    if (!this.project) {
+      alert('项目不存在,无法执行移出操作');
+      return;
+    }
+
+    const confirmMsg = `确定将 \"${member.name}\" 移出项目吗?`;
+    if (!confirm(confirmMsg)) return;
+
+    try {
+      this.loading = true;
+      const query = new Parse.Query('ProjectTeam');
+      const team = await query.get(member.projectTeamId);
+      team.set('isDeleted', true);
+      await team.save();
+
+      // 重新加载成员数据,保持列表与统计一致
+      await this.loadMembers();
+      alert(`✅ 已将 ${member.name} 移出项目`);
+    } catch (error) {
+      console.error('❌ 移出项目失败:', error);
+      alert(`移出失败: ${error instanceof Error ? error.message : '未知错误'}`);
+    } finally {
+      this.loading = false;
+    }
+  }
+
   getRoleBadgeClass(role: string): string {
     switch (role) {
       case '客服':