| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 | <!-- 模态框背景 --><div class="modal-overlay"     *ngIf="isVisible"     (click)="onBackdropClick($event)">  <!-- 模态框内容 -->  <div class="modal-container" (click)="$event.stopPropagation()">    <!-- 模态框头部 -->    <div class="modal-header">      <div class="header-left">        <h2 class="modal-title">          <svg class="title-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">            <path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path>            <circle cx="9" cy="7" r="4"></circle>            <path d="M23 21v-2a4 4 0 0 0-3-3.87"></path>            <path d="M16 3.13a4 4 0 0 1 0 7.75"></path>          </svg>          项目成员        </h2>        <div class="member-stats">          <span class="stat-item">            <span class="stat-number">{{ totalMembers }}</span>            <span class="stat-label">总成员</span>          </span>          <span class="stat-item">            <span class="stat-number">{{ projectTeamMembers }}</span>            <span class="stat-label">项目团队</span>          </span>          @if (pendingAddMembers > 0) {            <span class="stat-item stat-pending">              <span class="stat-number">{{ pendingAddMembers }}</span>              <span class="stat-label">待加入群聊</span>            </span>          }        </div>        <!-- 环境指示器 -->        <div class="environment-indicator">          @if (isWxworkEnvironment) {            <span class="env-badge env-wxwork">              <svg viewBox="0 0 24 24" fill="currentColor" width="16" height="16">                <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.88c0 .53-.21.9-.74.26-.18.07-.36.06-.51.14-.75.21-.13.18-.3.36-.3.75.06.39.12.69.12.75.21.37.12.69.12 1.06 0 .39-.13.7-.12.75-.06-.06-.18-.15-.51-.14-.75-.21-.53-.21-.9-.74-.26-.18-.07-.36-.06-.51-.14-.75-.21-.13-.18-.3-.36-.3-.75.06-.39.12-.69.12-.75-.21-.37-.12-.69-.12-1.06 0-.39.13-.7-.12-.75.06-.06.18-.15.51-.14-.75.21z"/>              </svg>              企业微信环境            </span>          } @else {            <span class="env-badge env-default">              <svg viewBox="0 0 24 24" fill="currentColor" width="16" height="16">                <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 17.88c0 .53-.21.9-.74.26-.18.07-.36.06-.51.14-.75.21-.13.18-.3.36-.3.75.06.39.12.69.12.75.21.37.12.69.12 1.06 0 .39-.13.7-.12.75-.06-.06-.18-.15-.51-.14-.75-.21-.53-.21-.9-.74-.26-.18-.07-.36-.06-.51-.14-.75-.21-.13-.18-.3-.36-.3-.75.06-.39.12-.69.12-.75-.21-.37-.12-.69-.12-1.06 0-.39.13-.7-.12-.75.06-.06.18-.15.51-.14-.75.21z"/>              </svg>              普通环境            </span>          }        </div>      </div>      <div class="header-right">                <!-- 搜索框 -->        <div class="search-box">          <svg class="search-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">            <circle cx="11" cy="11" r="8"></circle>            <path d="m21 21-4.35-4.35"></path>          </svg>          <input            type="text"            class="search-input"            placeholder="搜索成员..."            [(ngModel)]="searchQuery">        </div>        <!-- 过滤器 -->        <select class="filter-select" [(ngModel)]="memberFilter">          <option value="all">全部成员</option>          <option value="team">项目团队</option>          <option value="ingroup">已在群聊</option>          <option value="pending">待加入群聊</option>        </select>        <!-- 关闭按钮 -->        <button class="close-btn" (click)="onClose()">          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">            <line x1="18" y1="6" x2="6" y2="18"></line>            <line x1="6" y1="6" x2="18" y2="18"></line>          </svg>        </button>      </div>    </div>    <!-- 模态框内容 -->    <div class="modal-content">      <!-- 加载状态 -->      @if (loading) {        <div class="loading-state">          <div class="loading-spinner"></div>          <p>加载成员信息...</p>        </div>      } @else if (error) {        <!-- 错误状态 -->        <div class="error-state">          <svg class="error-icon" 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>          <h3>加载失败</h3>          <p>{{ error }}</p>          <button class="retry-btn" (click)="loadMembers()">重试</button>        </div>      } @else if (getFilteredMembers().length === 0) {        <!-- 空状态 -->        <div class="empty-state">          <svg class="empty-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">            <path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path>            <circle cx="9" cy="7" r="4"></circle>            <path d="M23 21v-2a4 4 0 0 0-3-3.87"></path>            <path d="M16 3.13a4 4 0 0 1 0 7.75"></path>          </svg>          <h3>暂无成员</h3>          <p>该项目还没有添加任何成员</p>        </div>      } @else {        <!-- 成员列表 -->        <div class="members-list">          @for (member of getFilteredMembers(); track member.id) {            <div class="member-card" [class]="getMemberStatusClass(member)">              <!-- 成员头像 -->              <div class="member-avatar">                @if (member.avatar) {                  <img [src]="member.avatar" [alt]="member.name" class="avatar-image" />                } @else {                  <div class="avatar-placeholder">                    {{ member.name.charAt(0).toUpperCase() }}                  </div>                }              </div>              <!-- 成员信息 -->              <div class="member-info">                <h4 class="member-name">{{ member.name }}</h4>                <div class="member-meta">                  <span class="member-role">                    <span class="role-badge" [class]="getRoleBadgeClass(member.role)">                      {{ member.role }}                    </span>                  </span>                  @if (member.department) {                    <span class="member-department">{{ member.department }}</span>                  }                  <span class="member-status" [class]="getMemberStatusClass(member)">                    {{ getMemberStatusText(member) }}                  </span>                </div>                @if (member.isInProjectTeam && !member.isInGroupChat && isWxworkEnvironment) {                  <div class="add-to-group-hint">                    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">                      <circle cx="12" cy="12" r="10"></circle>                      <line x1="12" y1="8" x2="12" y2="16"></line>                      <path d="M8 12h8"></path>                    </svg>                    <span>点击添加到群聊</span>                  </div>                }              </div>              <!-- 操作按钮 -->              <div class="member-actions">                @if (member.isInProjectTeam && !member.isInGroupChat ) {                  <button                    class="action-btn add-btn"                    (click)="addMemberToGroupChat(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="12" y1="8" x2="12" y2="16"></line>                      <path d="M8 12h8"></path>                    </svg>                    <span>邀请进群</span>                  </button>                }                <div class="status-indicator" [class]="getMemberStatusClass(member)">                  @if (member.isInProjectTeam && member.isInGroupChat) {                    <svg viewBox="0 0 24 24" fill="currentColor">                      <path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7.41l-1.41-1.41z"/>                    </svg>                  }                  @else if (member.isInProjectTeam && !member.isInGroupChat) {                    <svg viewBox="0 0 24 24" fill="currentColor">                      <circle cx="12" cy="12" r="10" opacity="0.3"/>                      <path d="M12 8v8"/>                      <path d="M8 12h8"/>                    </svg>                  }                  @else {                    <svg viewBox="0 0 24 24" fill="currentColor">                      <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15.88c0 .53-.21.9-.74.26-.18.07-.36.06-.51.14-.75.21-.13.18-.3.36-.3.75.06.39.12.69.12.75.21.37.12.69.12 1.06 0 .39-.13.7-.12.75-.06-.06-.18-.15-.51-.14-.75-.21-.53-.21-.9-.74-.26-.18-.07-.36-.06-.51-.14-.75-.21-.13-.18-.3-.36-.3-.75.06-.39.12-.69.12-.75-.21-.37-.12-.69-.12-1.06 0-.39.13-.7-.12-.75.06-.06.18-.15.51-.14-.75.21z"/>                    </svg>                  }                </div>              </div>            </div>          }        </div>      }    </div>  </div></div>
 |