groupchats.html 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. <div class="groupchats-container">
  2. <div class="page-header">
  3. <div>
  4. <h1>群组管理</h1>
  5. <p class="subtitle">管理企业微信群聊与项目关联 (数据从企业微信同步)</p>
  6. </div>
  7. <button class="btn btn-secondary" (click)="exportGroupChats()">导出</button>
  8. </div>
  9. <div class="stats-cards">
  10. <div class="stat-card">
  11. <div class="stat-value">{{ total() }}</div>
  12. <div class="stat-label">群组总数</div>
  13. </div>
  14. </div>
  15. <div class="filter-bar">
  16. <input
  17. type="text"
  18. class="search-input"
  19. placeholder="搜索群名称..."
  20. [ngModel]="keyword()"
  21. (ngModelChange)="keyword.set($event)"
  22. />
  23. <button class="btn btn-text" (click)="resetFilters()">重置</button>
  24. </div>
  25. <div *ngIf="loading()" class="loading-state">加载中...</div>
  26. <div *ngIf="!loading()" class="data-table">
  27. <table>
  28. <thead>
  29. <tr>
  30. <th>群名称</th>
  31. <th>企微群ID</th>
  32. <th>关联项目</th>
  33. <th>成员数</th>
  34. <th>状态</th>
  35. <th width="120">操作</th>
  36. </tr>
  37. </thead>
  38. <tbody>
  39. <tr *ngFor="let group of filtered" [class.disabled]="group.isDisabled">
  40. <td>{{ group.name }}</td>
  41. <td><code>{{ group.chat_id }}</code></td>
  42. <td>{{ group.project || '未关联' }}</td>
  43. <td>{{ group.memberCount }}</td>
  44. <td>
  45. <span [class]="'status ' + (group.isDisabled ? 'disabled' : 'active')">
  46. {{ group.isDisabled ? '已禁用' : '正常' }}
  47. </span>
  48. </td>
  49. <td>
  50. <button class="btn-icon" (click)="viewGroupChat(group)">👁</button>
  51. <button class="btn-icon" (click)="editGroupChat(group)">✏️</button>
  52. <button class="btn-icon" (click)="toggleGroupChat(group)">
  53. {{ group.isDisabled ? '✓' : '🚫' }}
  54. </button>
  55. </td>
  56. </tr>
  57. <tr *ngIf="filtered.length === 0">
  58. <td colspan="6" class="empty-state">暂无数据</td>
  59. </tr>
  60. </tbody>
  61. </table>
  62. </div>
  63. <!-- 侧边面板 -->
  64. <div class="side-panel" [class.open]="showPanel">
  65. <div class="panel-overlay" (click)="closePanel()"></div>
  66. <div class="panel-content">
  67. <div class="panel-header">
  68. <h2>{{ panelMode === 'edit' ? '编辑群组' : '群组详情' }}</h2>
  69. <button class="btn-close" (click)="closePanel()">×</button>
  70. </div>
  71. <div class="panel-body" *ngIf="currentGroupChat">
  72. <div *ngIf="panelMode === 'detail'" class="detail-view">
  73. <div class="detail-item"><label>群名称</label><div>{{ currentGroupChat.name }}</div></div>
  74. <div class="detail-item"><label>企微群ID</label><div><code>{{ currentGroupChat.chat_id }}</code></div></div>
  75. <div class="detail-item"><label>关联项目</label><div>{{ currentGroupChat.project || '未关联' }}</div></div>
  76. <div class="detail-item"><label>成员数</label><div>{{ currentGroupChat.memberCount }}</div></div>
  77. <div class="detail-item"><label>状态</label><div>{{ currentGroupChat.isDisabled ? '已禁用' : '正常' }}</div></div>
  78. </div>
  79. <div *ngIf="panelMode === 'edit'" class="form-view">
  80. <div class="form-group">
  81. <label>关联项目</label>
  82. <select class="form-control" [(ngModel)]="formModel.projectId">
  83. <option [value]="undefined">未关联</option>
  84. <option *ngFor="let proj of projects()" [value]="proj.id">{{ proj.title }}</option>
  85. </select>
  86. </div>
  87. <div class="form-group">
  88. <label>
  89. <input type="checkbox" [(ngModel)]="formModel.isDisabled" />
  90. 禁用此群组
  91. </label>
  92. </div>
  93. </div>
  94. </div>
  95. <div class="panel-footer" *ngIf="panelMode === 'edit'">
  96. <button class="btn btn-default" (click)="closePanel()">取消</button>
  97. <button class="btn btn-primary" (click)="updateGroupChat()">更新</button>
  98. </div>
  99. </div>
  100. </div>
  101. </div>