123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726 |
- <div class="complaint-card">
- <!-- 企业微信监控控制区域 -->
- <div class="wechat-monitoring-section">
- <div class="monitoring-header">
- <h4>企业微信投诉监控</h4>
- <div class="monitoring-status" [class]="'status-' + realTimeTaskStatus()">
- {{ realTimeTaskStatus() === 'idle' ? '未启动' :
- realTimeTaskStatus() === 'processing' ? '监控中' : '已启动' }}
- </div>
- </div>
-
- <div class="monitoring-controls">
- <button class="btn btn-primary"
- (click)="startWeChatMonitoring()"
- [disabled]="realTimeTaskStatus() === 'processing'">
- <i class="fas fa-play"></i>
- 启动监控
- </button>
-
- <button class="btn btn-secondary"
- (click)="setupKeywordMonitoring()">
- <i class="fas fa-cog"></i>
- 关键词设置
- </button>
-
- <div class="monitoring-stats">
- <span class="stat-item">
- <i class="fas fa-eye"></i>
- 监控群组: {{ monitoredGroups || 5 }}
- </span>
- <span class="stat-item">
- <i class="fas fa-bell"></i>
- 今日检测: {{ todayDetections || 3 }}
- </span>
- </div>
- </div>
- </div>
- <!-- 实时代办项处理区域 -->
- <div class="realtime-tasks-section" *ngIf="realTimeTaskStatus() !== 'idle'">
- <div class="section-header">
- <h4>实时代办项</h4>
- <span class="task-count">{{ urgentComplaints().length }} 项待处理</span>
- </div>
-
- <div class="realtime-task-list">
- <div class="task-item"
- *ngFor="let complaint of urgentComplaints()"
- [class.processing]="processingTaskId() === complaint.id">
- <div class="task-info">
- <div class="task-title">{{ complaint.description }}</div>
- <div class="task-meta">
- <span class="customer">{{ complaint.customerName }}</span>
- <span class="time">{{ complaint.submitTime | date:'HH:mm' }}</span>
- <span class="urgency" [class]="'urgency-' + complaint.urgencyLevel">
- {{ complaint.urgencyLevel === 'critical' ? '紧急' : '重要' }}
- </span>
- </div>
- </div>
-
- <div class="task-actions">
- <button class="btn btn-sm btn-primary"
- (click)="processRealTimeTask(complaint.id)"
- [disabled]="processingTaskId() === complaint.id">
- <i class="fas fa-play" *ngIf="processingTaskId() !== complaint.id"></i>
- <i class="fas fa-spinner fa-spin" *ngIf="processingTaskId() === complaint.id"></i>
- {{ processingTaskId() === complaint.id ? '处理中' : '立即处理' }}
- </button>
-
- <button class="btn btn-sm btn-warning"
- (click)="escalateComplaint(complaint)">
- <i class="fas fa-arrow-up"></i>
- 升级
- </button>
- </div>
- </div>
- </div>
- </div>
- <!-- 企业微信监控控制面板 -->
- <div class="wechat-monitoring-panel">
- <h4>企业微信投诉监控</h4>
- <div class="monitoring-controls">
- <button class="control-btn start-monitoring" (click)="startWeChatMonitoring()">
- <span class="btn-icon">📱</span>
- 开始微信监控
- </button>
- <button class="control-btn setup-keywords" (click)="setupKeywordMonitoring()">
- <span class="btn-icon">🔍</span>
- 设置关键词
- </button>
- <div class="monitoring-status">
- <span class="status-label">监控状态:</span>
- <span class="status-indicator active">运行中</span>
- </div>
- </div>
-
- <div class="keyword-display">
- <span class="keyword-label">监控关键词:</span>
- <div class="keyword-tags">
- @for (keyword of monitorKeywords; track keyword) {
- <span class="keyword-tag">{{ keyword }}</span>
- }
- </div>
- </div>
- </div>
- <!-- 实时代办项状态 -->
- @if (realTimeTaskStatus() !== 'idle') {
- <div class="real-time-task-status">
- <div class="task-status-header">
- <h5>实时代办项处理</h5>
- <span class="task-status-badge" [class]="realTimeTaskStatus()">
- {{ realTimeTaskStatus() === 'processing' ? '处理中...' : '已完成' }}
- </span>
- </div>
- @if (realTimeTaskStatus() === 'processing') {
- <div class="task-progress">
- <div class="progress-bar">
- <div class="progress-fill"></div>
- </div>
- <span class="progress-text">正在创建代办项:{{ processingTaskId() }}</span>
- </div>
- }
- </div>
- }
- <!-- 优先级统计 -->
- <div class="priority-stats">
- <h5>优先级分布</h5>
- <div class="priority-cards-grid">
- @for (priority of priorities; track priority.value) {
- <div class="priority-card" [style.border-color]="priority.color">
- <div class="priority-card-header" [style.background-color]="priority.color">
- <span class="priority-card-label">{{ priority.label }}</span>
- </div>
- <div class="priority-card-body">
- <div class="priority-card-count">{{ stats().priorityStats[priority.value] || 0 }}</div>
- <div class="priority-card-suffix">个</div>
- </div>
- </div>
- }
- </div>
- </div>
- <!-- 类型统计 -->
- <div class="type-stats">
- <h5>问题类型统计</h5>
- <div class="type-grid">
- @for (type of complaintTypes; track type.value) {
- <div class="type-item">
- <span class="type-label">{{ type.label }}</span>
- <span class="type-count">{{ stats().typeStats[type.value] || 0 }}</span>
- </div>
- }
- </div>
- </div>
- <!-- 筛选区域 -->
- <div class="filter-section">
- <div class="search-row">
- <div class="search-group">
- <label>搜索:</label>
- <input
- type="text"
- class="search-input"
- placeholder="搜索投诉内容、客户姓名..."
- [value]="searchKeyword()"
- (input)="updateSearchKeyword($event.target.value)">
- </div>
- </div>
- <div class="filter-row">
- <div class="filter-group">
- <label>状态筛选:</label>
- <div class="filter-buttons">
- <button
- class="filter-btn"
- [class.active]="statusFilter() === 'all'"
- (click)="updateStatusFilter('all')">
- 全部
- </button>
- <button
- class="filter-btn pending"
- [class.active]="statusFilter() === 'pending'"
- (click)="updateStatusFilter('pending')">
- 待处理
- </button>
- <button
- class="filter-btn processing"
- [class.active]="statusFilter() === 'processing'"
- (click)="updateStatusFilter('processing')">
- 处理中
- </button>
- <button
- class="filter-btn resolved"
- [class.active]="statusFilter() === 'resolved'"
- (click)="updateStatusFilter('resolved')">
- 已解决
- </button>
- </div>
- </div>
- </div>
-
- <div class="filter-row">
- <div class="filter-group">
- <label>优先级筛选:</label>
- <select
- class="filter-select"
- [value]="priorityFilter()"
- (change)="updatePriorityFilter($event)">
- <option value="all">全部优先级</option>
- @for (priority of priorities; track priority.value) {
- <option [value]="priority.value">{{ priority.label }}</option>
- }
- </select>
- </div>
-
- <div class="filter-group">
- <label>类型筛选:</label>
- <select
- class="filter-select"
- [value]="typeFilter()"
- (change)="updateTypeFilter($event)">
- <option value="all">全部类型</option>
- @for (type of complaintTypes; track type.value) {
- <option [value]="type.value">{{ type.label }}</option>
- }
- </select>
- </div>
- <!-- 新增筛选项 -->
- <div class="filter-group">
- <label>来源筛选:</label>
- <select
- class="filter-select"
- [value]="sourceFilter()"
- (change)="updateSourceFilter($event)">
- <option value="all">全部来源</option>
- @for (source of complaintSources; track source.value) {
- <option [value]="source.value">{{ source.icon }} {{ source.label }}</option>
- }
- </select>
- </div>
- <div class="filter-group">
- <label>紧急程度:</label>
- <select
- class="filter-select"
- [value]="urgencyFilter()"
- (change)="updateUrgencyFilter($event)">
- <option value="all">全部级别</option>
- @for (urgency of urgencyLevels; track urgency.value) {
- <option [value]="urgency.value">{{ urgency.label }}</option>
- }
- </select>
- </div>
- </div>
- </div>
- <!-- 投诉列表 -->
- <div class="complaints-list">
- @if (filteredComplaints() && filteredComplaints().length > 0) {
- <div class="complaints-grid">
- @for (complaint of filteredComplaints(); track complaint.id) {
- <div class="complaint-card-item" [class]="getStatusClass(complaint)" [class.overdue]="isOverdue(complaint)">
- <!-- 卡片头部 -->
- <div class="card-header">
- <div class="header-left">
- <span class="type-tag" [class]="getComplaintType(complaint)">{{ getTypeLabel(getComplaintType(complaint)) }}</span>
- <div class="priority-badge" [class]="getPriorityClass(complaint.priority || 'low')" [style.background-color]="getPriorityInfo(complaint.priority || 'low').color">
- {{ getPriorityInfo(complaint.priority || 'low').label }}优先级
- </div>
- <!-- 新增来源标识 -->
- <div class="source-badge" [class]="complaint.source">
- {{ getComplaintSourceInfo(complaint).icon }} {{ getComplaintSourceInfo(complaint).label }}
- </div>
- <!-- 紧急程度标识 -->
- @if (complaint.urgencyLevel && complaint.urgencyLevel !== 'normal') {
- <div class="urgency-badge" [style.background-color]="getUrgencyInfo(complaint).color">
- {{ getUrgencyInfo(complaint).label }}
- </div>
- }
- <!-- 自动标注标识 -->
- @if (isAutoTagged(complaint)) {
- <span class="auto-tag-badge">🤖 自动</span>
- }
- <!-- 升级标识 -->
- @if (complaint.escalationLevel && complaint.escalationLevel > 0) {
- <span class="escalation-badge">⬆️ {{ getEscalationDisplay(complaint.escalationLevel) }}</span>
- }
- </div>
- <div class="header-right">
- <span class="status-badge" [class]="getStatusClass(complaint)">
- {{ complaint.status }}
- </span>
- @if (isOverdue(complaint)) {
- <span class="overdue-badge">超时</span>
- }
- @if (complaint.followUpRequired) {
- <span class="follow-up-badge">需跟进</span>
- }
- </div>
- </div>
-
- <!-- 卡片主体 -->
- <div class="card-body">
- @if (complaint.customerName) {
- <div class="customer-info">
- <span class="customer-label">客户:</span>
- <span class="customer-name">{{ complaint.customerName }}</span>
- </div>
- }
- <!-- 微信相关信息 -->
- @if (complaint.source === 'wechat_auto' && complaint.wechatGroupName) {
- <div class="wechat-info">
- <span class="wechat-label">📱 微信群:</span>
- <span class="wechat-group">{{ complaint.wechatGroupName }}</span>
- @if (complaint.keywordMatched && complaint.keywordMatched.length > 0) {
- <div class="matched-keywords">
- <span class="keyword-label">匹配关键词:</span>
- @for (keyword of complaint.keywordMatched; track keyword) {
- <span class="matched-keyword">{{ keyword }}</span>
- }
- </div>
- }
- </div>
- }
- <!-- 分配信息 -->
- @if (complaint.assignedTo) {
- <div class="assignment-info">
- <span class="assignment-label">👤 处理人:</span>
- <span class="assignee-name">{{ complaint.assignedTo }}</span>
- </div>
- }
- <!-- 标签显示 -->
- @if (complaint.tags && complaint.tags.length > 0) {
- <div class="tags-section">
- <span class="tags-label">🏷️ 标签:</span>
- <div class="tags-list">
- @for (tag of complaint.tags; track tag) {
- <span class="complaint-tag">{{ tag }}</span>
- }
- </div>
- </div>
- }
-
- <div class="complaint-description">
- <h4>投诉内容</h4>
- <p>{{ complaint.description }}</p>
- </div>
-
- @if (complaint.images && complaint.images.length > 0) {
- <div class="complaint-images">
- <h5>相关图片</h5>
- <div class="images-grid">
- @for (image of complaint.images; track $index) {
- <img [src]="image" [alt]="'投诉图片' + ($index + 1)" class="complaint-image">
- }
- </div>
- </div>
- }
-
- <div class="time-section">
- <div class="time-item">
- <span class="time-label">提交时间:</span>
- <span class="time-value">{{ complaint.submittedAt | date:'yyyy-MM-dd HH:mm' }}</span>
- </div>
- <div class="time-item">
- <span class="time-label">处理天数:</span>
- <span class="time-value">{{ getDaysInProgress(complaint) }} 天</span>
- </div>
- @if (complaint.resolvedAt) {
- <div class="time-item">
- <span class="time-label">解决时间:</span>
- <span class="time-value">{{ complaint.resolvedAt | date:'yyyy-MM-dd HH:mm' }}</span>
- </div>
- }
- </div>
-
- @if (complaint.handlerComment) {
- <div class="handler-section">
- <h5>处理意见</h5>
- <p class="handler-comment">{{ complaint.handlerComment }}</p>
- @if (complaint.handlerName) {
- <div class="handler-info">
- <span class="handler-label">处理人:</span>
- <span class="handler-name">{{ complaint.handlerName }}</span>
- </div>
- }
- </div>
- }
-
- @if (complaint.solution) {
- <div class="solution-section">
- <h5>解决方案</h5>
- <p class="solution-text">{{ complaint.solution }}</p>
- </div>
- }
- </div>
-
- <!-- 卡片底部操作按钮 -->
- <div class="card-footer">
- @if (complaint.status === '待处理') {
- <button class="action-btn process-btn" (click)="startProcessing(complaint)">
- <span class="btn-icon">🔧</span>
- 开始处理
- </button>
- <button class="action-btn task-btn" (click)="createRealTimeTask(complaint)">
- <span class="btn-icon">📋</span>
- 创建代办项
- </button>
- } @else if (complaint.status === '处理中') {
- <button class="action-btn complete-btn" (click)="completeProcessing(complaint)">
- <span class="btn-icon">✅</span>
- 完成处理
- </button>
- } @else if (complaint.status === '已解决') {
- <div class="completed-status">
- <span class="completed-icon">✓</span>
- <span class="completed-text">处理完成</span>
- </div>
- }
-
- @if (complaint.status !== '已解决') {
- <button class="action-btn detail-btn" (click)="viewDetails(complaint)">
- <span class="btn-icon">👁️</span>
- 查看详情
- </button>
-
- <!-- 新增操作按钮 -->
- @if (complaint.escalationLevel !== undefined && complaint.escalationLevel < 3) {
- <button class="action-btn escalate-btn" (click)="escalateComplaint(complaint)">
- <span class="btn-icon">⬆️</span>
- 升级处理
- </button>
- }
-
- <button class="action-btn assign-btn" (click)="assignComplaint(complaint, '处理员A')">
- <span class="btn-icon">👤</span>
- 分配处理
- </button>
-
- <button class="action-btn tag-btn" (click)="addComplaintTag(complaint)">
- <span class="btn-icon">🏷️</span>
- 添加标签
- </button>
-
- @if (!complaint.followUpRequired) {
- <button class="action-btn follow-up-btn" (click)="setFollowUpRequired(complaint, true)">
- <span class="btn-icon">📞</span>
- 设置跟进
- </button>
- } @else {
- <button class="action-btn follow-up-btn active" (click)="setFollowUpRequired(complaint, false)">
- <span class="btn-icon">✓</span>
- 取消跟进
- </button>
- }
- }
- </div>
- </div>
- }
- </div>
- } @else {
- <div class="empty-state">
- <div class="empty-icon">📋</div>
- <div class="empty-title">暂无投诉记录</div>
- <div class="empty-description">当前没有符合筛选条件的投诉记录</div>
- </div>
- }
- </div>
- <!-- 投诉详情弹窗 -->
- @if (showDetailModal() && selectedComplaint()) {
- <div class="modal-overlay" (click)="closeDetailModal()">
- <div class="modal-content complaint-detail-modal" (click)="$event.stopPropagation()">
- <div class="modal-header">
- <h3>📋 投诉详情</h3>
- <button class="close-btn" (click)="closeDetailModal()">
- <span>✕</span>
- </button>
- </div>
- <div class="modal-body">
- @if (selectedComplaint(); as complaint) {
- <!-- 基本信息 -->
- <div class="detail-section">
- <h4 class="section-title">基本信息</h4>
- <div class="info-grid">
- <div class="info-item">
- <span class="label">投诉ID:</span>
- <span class="value">{{ complaint.id }}</span>
- </div>
- <div class="info-item">
- <span class="label">客户姓名:</span>
- <span class="value">{{ complaint.customerName || '未提供' }}</span>
- </div>
- <div class="info-item">
- <span class="label">投诉类型:</span>
- <span class="value type-badge" [class]="getComplaintType(complaint)">
- {{ getTypeLabel(getComplaintType(complaint)) }}
- </span>
- </div>
- <div class="info-item">
- <span class="label">优先级:</span>
- <span class="value priority-badge" [style.background-color]="getPriorityInfo(complaint.priority || 'low').color">
- {{ getPriorityInfo(complaint.priority || 'low').label }}
- </span>
- </div>
- <div class="info-item">
- <span class="label">状态:</span>
- <span class="value status-badge" [class]="getStatusClass(complaint)">
- {{ complaint.status }}
- </span>
- </div>
- <div class="info-item">
- <span class="label">来源:</span>
- <span class="value source-badge">
- {{ getComplaintSourceInfo(complaint).icon }} {{ getComplaintSourceInfo(complaint).label }}
- </span>
- </div>
- </div>
- </div>
- <!-- 投诉内容 -->
- <div class="detail-section">
- <h4 class="section-title">投诉内容</h4>
- <div class="complaint-content-box">
- <p>{{ complaint.description }}</p>
- </div>
- </div>
- <!-- 微信相关信息 -->
- @if (complaint.source === 'wechat_auto' && complaint.wechatGroupName) {
- <div class="detail-section">
- <h4 class="section-title">📱 微信信息</h4>
- <div class="info-grid">
- <div class="info-item">
- <span class="label">微信群:</span>
- <span class="value">{{ complaint.wechatGroupName }}</span>
- </div>
- @if (complaint.keywordMatched && complaint.keywordMatched.length > 0) {
- <div class="info-item full-width">
- <span class="label">匹配关键词:</span>
- <div class="keyword-tags">
- @for (keyword of complaint.keywordMatched; track keyword) {
- <span class="keyword-tag">{{ keyword }}</span>
- }
- </div>
- </div>
- }
- </div>
- </div>
- }
- <!-- 标签 -->
- @if (complaint.tags && complaint.tags.length > 0) {
- <div class="detail-section">
- <h4 class="section-title">🏷️ 标签</h4>
- <div class="tags-display">
- @for (tag of complaint.tags; track tag) {
- <span class="tag-item">
- {{ tag }}
- <button class="tag-remove" (click)="removeTag(complaint, tag)">×</button>
- </span>
- }
- </div>
- </div>
- }
- <!-- 相关图片 -->
- @if (complaint.images && complaint.images.length > 0) {
- <div class="detail-section">
- <h4 class="section-title">📷 相关图片</h4>
- <div class="images-gallery">
- @for (image of complaint.images; track $index) {
- <img [src]="image" [alt]="'投诉图片' + ($index + 1)" class="gallery-image">
- }
- </div>
- </div>
- }
- <!-- 处理信息 -->
- <div class="detail-section">
- <h4 class="section-title">处理信息</h4>
- <div class="info-grid">
- <div class="info-item">
- <span class="label">提交时间:</span>
- <span class="value">{{ complaint.submittedAt | date:'yyyy-MM-dd HH:mm' }}</span>
- </div>
- <div class="info-item">
- <span class="label">处理天数:</span>
- <span class="value" [class.warning]="isOverdue(complaint)">
- {{ getDaysInProgress(complaint) }} 天
- </span>
- </div>
- @if (complaint.assignedTo) {
- <div class="info-item">
- <span class="label">处理人:</span>
- <span class="value">{{ complaint.assignedTo }}</span>
- </div>
- }
- @if (complaint.resolvedAt) {
- <div class="info-item">
- <span class="label">解决时间:</span>
- <span class="value">{{ complaint.resolvedAt | date:'yyyy-MM-dd HH:mm' }}</span>
- </div>
- }
- </div>
- </div>
- <!-- 处理意见 -->
- @if (complaint.handlerComment) {
- <div class="detail-section">
- <h4 class="section-title">处理意见</h4>
- <div class="comment-box">
- <p>{{ complaint.handlerComment }}</p>
- @if (complaint.handlerName) {
- <div class="comment-author">—— {{ complaint.handlerName }}</div>
- }
- </div>
- </div>
- }
- <!-- 解决方案 -->
- @if (complaint.solution) {
- <div class="detail-section">
- <h4 class="section-title">✅ 解决方案</h4>
- <div class="solution-box">
- <p>{{ complaint.solution }}</p>
- </div>
- </div>
- }
- }
- </div>
- <div class="modal-footer">
- <button class="btn btn-secondary" (click)="closeDetailModal()">关闭</button>
- @if (selectedComplaint() && selectedComplaint()!.status !== '已解决') {
- <button class="btn btn-primary" (click)="addComplaintTag(selectedComplaint()!); closeDetailModal()">
- <i class="fas fa-tag"></i>
- 添加标签
- </button>
- }
- </div>
- </div>
- </div>
- }
- <!-- 添加标签弹窗 -->
- @if (showTagModal() && tagModalComplaint()) {
- <div class="modal-overlay" (click)="closeTagModal()">
- <div class="modal-content tag-modal" (click)="$event.stopPropagation()">
- <div class="modal-header">
- <h3>🏷️ 添加标签</h3>
- <button class="close-btn" (click)="closeTagModal()">
- <span>✕</span>
- </button>
- </div>
- <div class="modal-body">
- @if (tagModalComplaint(); as complaint) {
- <!-- 当前标签 -->
- @if (complaint.tags && complaint.tags.length > 0) {
- <div class="current-tags-section">
- <h4 class="section-title">当前标签</h4>
- <div class="current-tags">
- @for (tag of complaint.tags; track tag) {
- <span class="tag-item">
- {{ tag }}
- <button class="tag-remove" (click)="removeTag(complaint, tag)">×</button>
- </span>
- }
- </div>
- </div>
- }
- <!-- 预设标签 -->
- <div class="preset-tags-section">
- <h4 class="section-title">预设标签</h4>
- <div class="preset-tags-grid">
- @for (tag of presetTags; track tag) {
- <button
- class="preset-tag-btn"
- [class.selected]="complaint.tags?.includes(tag)"
- (click)="selectPresetTag(tag)">
- {{ tag }}
- </button>
- }
- </div>
- </div>
- <!-- 自定义标签 -->
- <div class="custom-tag-section">
- <h4 class="section-title">自定义标签</h4>
- <div class="custom-tag-input-group">
- <input
- type="text"
- class="custom-tag-input"
- placeholder="输入自定义标签..."
- [value]="newTagInput()"
- (input)="newTagInput.set($any($event.target).value)"
- (keyup.enter)="addCustomTag()">
- <button class="btn btn-primary" (click)="addCustomTag()">
- 添加
- </button>
- </div>
- </div>
- }
- </div>
- <div class="modal-footer">
- <button class="btn btn-secondary" (click)="closeTagModal()">取消</button>
- <button class="btn btn-primary" (click)="closeTagModal()">
- <i class="fas fa-check"></i>
- 完成
- </button>
- </div>
- </div>
- </div>
- }
- </div>
|