123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726 |
- import { Component, Input, computed, signal } from '@angular/core';
- import { CommonModule } from '@angular/common';
- import { FormsModule } from '@angular/forms';
- export interface ComplaintItem {
- id: string;
- type: string;
- description: string;
- submitTime: any;
- submittedAt?: Date;
- resolvedAt?: Date;
- status: string;
- response?: string;
- handlerComment?: string;
- handlerName?: string;
- solution?: string;
- customerName?: string;
- priority?: string;
- images?: string[];
- // 新增字段
- source?: 'manual' | 'wechat_auto' | 'keyword_monitor'; // 投诉来源
- wechatGroupName?: string; // 企业微信群名称
- wechatMessageId?: string; // 微信消息ID
- keywordMatched?: string[]; // 匹配的关键词
- autoTagged?: boolean; // 是否自动标注
- urgencyLevel?: 'normal' | 'urgent' | 'critical'; // 紧急程度
- assignedTo?: string; // 分配给谁处理
- estimatedResolutionTime?: Date; // 预计解决时间
- actualResolutionTime?: Date; // 实际解决时间
- customerSatisfaction?: number; // 客户满意度评分
- followUpRequired?: boolean; // 是否需要后续跟进
- relatedProjectId?: string; // 关联项目ID
- escalationLevel?: number; // 升级级别 (0-3)
- tags?: string[]; // 标签
- }
- interface ComplaintStats {
- totalCount: number;
- pendingCount: number;
- processingCount: number;
- resolvedCount: number;
- highPriorityCount: number;
- averageResolutionTime: number;
- priorityStats: { [key: string]: number };
- typeStats: { [key: string]: number };
- // 新增统计字段
- sourceStats: { [key: string]: number };
- urgencyStats: { [key: string]: number };
- escalationStats: { [key: string]: number };
- autoTaggedCount: number;
- wechatComplaintCount: number;
- keywordMonitorCount: number;
- overdueCount: number;
- followUpRequiredCount: number;
- }
- @Component({
- selector: 'app-complaint-card',
- standalone: true,
- imports: [CommonModule, FormsModule],
- templateUrl: './complaint-card.html',
- styleUrls: ['./complaint-card.scss']
- })
- export class ComplaintCardComponent {
- @Input() complaints: ComplaintItem[] = [];
- // 筛选条件
- statusFilter = signal<string>('all');
- priorityFilter = signal<string>('all');
- typeFilter = signal<string>('all');
- searchKeyword = signal<string>('');
- sourceFilter = signal<string>('all');
- urgencyFilter = signal<string>('all');
- // 新增缺失的属性
- monitoredGroups = 5; // 监控群组数量
- todayDetections = 3; // 今日检测数量
-
- // 详情弹窗状态
- showDetailModal = signal<boolean>(false);
- selectedComplaint = signal<ComplaintItem | null>(null);
-
- // 添加标签弹窗状态
- showTagModal = signal<boolean>(false);
- tagModalComplaint = signal<ComplaintItem | null>(null);
- newTagInput = signal<string>('');
-
- // 预设标签列表
- presetTags = [
- '质量问题', '服务态度', '延期交付', '沟通不畅',
- '设计不满', '价格争议', '技术问题', '售后服务',
- '紧急处理', '重要客户', '需要跟进', '已协商'
- ];
-
- // 紧急投诉计算属性
- urgentComplaints = computed(() => {
- return this.complaints.filter(complaint =>
- complaint.urgencyLevel === 'urgent' ||
- complaint.urgencyLevel === 'critical' ||
- complaint.priority === 'urgent' ||
- complaint.priority === 'high'
- );
- });
- // 投诉来源选项
- complaintSources = [
- { value: 'manual', label: '人工创建', icon: '👥' },
- { value: 'wechat_auto', label: '微信自动', icon: '🤖' },
- { value: 'keyword_monitor', label: '关键词监控', icon: '🔍' }
- ];
- // 紧急程度选项
- urgencyLevels = [
- { value: 'normal', label: '普通', color: '#52c41a' },
- { value: 'urgent', label: '紧急', color: '#faad14' },
- { value: 'critical', label: '严重', color: '#f5222d' }
- ];
- // 关键词监控配置
- monitorKeywords = ['不满意', '投诉', '退款', '差评', '问题', '延期', '质量差'];
- // 实时代办项状态
- realTimeTaskStatus = signal<'idle' | 'processing' | 'completed'>('idle');
- processingTaskId = signal<string>('');
- // 投诉类型
- complaintTypes = [
- { value: 'quality', label: '质量问题' },
- { value: 'service', label: '服务态度' },
- { value: 'delivery', label: '交付延期' },
- { value: 'communication', label: '沟通问题' },
- { value: 'design', label: '设计不满意' },
- { value: 'other', label: '其他问题' }
- ];
- // 优先级选项
- priorities = [
- { value: 'low', label: '低', color: '#52c41a' },
- { value: 'medium', label: '中', color: '#faad14' },
- { value: 'high', label: '高', color: '#f5222d' },
- { value: 'urgent', label: '紧急', color: '#722ed1' }
- ];
- // 计算统计数据
- stats = computed<ComplaintStats>(() => {
- const complaints = this.complaints || [];
- const totalCount = complaints.length;
-
- const pendingCount = complaints.filter(c => c.status === '待处理').length;
- const processingCount = complaints.filter(c => c.status === '处理中').length;
- const resolvedCount = complaints.filter(c => c.status === '已解决').length;
- const highPriorityCount = complaints.filter(c => (c as any).priority === 'high' || (c as any).priority === 'urgent').length;
- // 计算平均解决时间(天)
- const resolvedComplaints = complaints.filter(c => c.status === '已解决' && (c as any).resolvedAt && (c as any).createdAt);
- const averageResolutionTime = resolvedComplaints.length > 0
- ? resolvedComplaints.reduce((sum, c) => {
- const days = Math.ceil((new Date((c as any).resolvedAt).getTime() - new Date((c as any).createdAt).getTime()) / (1000 * 60 * 60 * 24));
- return sum + days;
- }, 0) / resolvedComplaints.length
- : 0;
- // 优先级统计
- const priorityStats: { [key: string]: number } = {};
- this.priorities.forEach(p => {
- priorityStats[p.value] = complaints.filter(c => (c as any).priority === p.value).length;
- });
- // 类型统计
- const typeStats: { [key: string]: number } = {};
- this.complaintTypes.forEach(t => {
- typeStats[t.value] = complaints.filter(c => this.getComplaintType(c) === t.value).length;
- });
- // 来源统计
- const sourceStats: { [key: string]: number } = {};
- this.complaintSources.forEach(s => {
- sourceStats[s.value] = complaints.filter(c => c.source === s.value).length;
- });
- // 紧急程度统计
- const urgencyStats: { [key: string]: number } = {};
- this.urgencyLevels.forEach(u => {
- urgencyStats[u.value] = complaints.filter(c => c.urgencyLevel === u.value).length;
- });
- // 升级级别统计
- const escalationStats: { [key: string]: number } = {};
- for (let i = 0; i <= 3; i++) {
- escalationStats[i.toString()] = complaints.filter(c => c.escalationLevel === i).length;
- }
- // 其他统计
- const autoTaggedCount = complaints.filter(c => c.autoTagged === true).length;
- const wechatComplaintCount = complaints.filter(c => c.source === 'wechat_auto').length;
- const keywordMonitorCount = complaints.filter(c => c.source === 'keyword_monitor').length;
- const overdueCount = complaints.filter(c => this.isOverdue(c)).length;
- const followUpRequiredCount = complaints.filter(c => c.followUpRequired === true).length;
- return {
- totalCount,
- pendingCount,
- processingCount,
- resolvedCount,
- highPriorityCount,
- averageResolutionTime: Math.round(averageResolutionTime * 10) / 10,
- priorityStats,
- typeStats,
- sourceStats,
- urgencyStats,
- escalationStats,
- autoTaggedCount,
- wechatComplaintCount,
- keywordMonitorCount,
- overdueCount,
- followUpRequiredCount
- };
- });
- // 筛选后的投诉列表
- filteredComplaints = computed(() => {
- let filtered = this.complaints || [];
- // 状态筛选
- if (this.statusFilter() !== 'all') {
- const statusMap: { [key: string]: string } = {
- 'pending': '待处理',
- 'processing': '处理中',
- 'resolved': '已解决'
- };
- const targetStatus = statusMap[this.statusFilter()] || this.statusFilter();
- filtered = filtered.filter(complaint => complaint.status === targetStatus);
- }
- // 优先级筛选
- if (this.priorityFilter() !== 'all') {
- filtered = filtered.filter(complaint => (complaint as any).priority === this.priorityFilter());
- }
- // 类型筛选
- if (this.typeFilter() !== 'all') {
- filtered = filtered.filter(complaint => this.getComplaintType(complaint) === this.typeFilter());
- }
- // 来源筛选
- if (this.sourceFilter() !== 'all') {
- filtered = filtered.filter(complaint => complaint.source === this.sourceFilter());
- }
- // 紧急程度筛选
- if (this.urgencyFilter() !== 'all') {
- filtered = filtered.filter(complaint => complaint.urgencyLevel === this.urgencyFilter());
- }
- // 关键词搜索
- if (this.searchKeyword()) {
- const keyword = this.searchKeyword().toLowerCase();
- filtered = filtered.filter(complaint =>
- complaint.description?.toLowerCase().includes(keyword) ||
- (complaint as any).customerName?.toLowerCase().includes(keyword) ||
- complaint.type?.toLowerCase().includes(keyword) ||
- complaint.wechatGroupName?.toLowerCase().includes(keyword) ||
- complaint.tags?.some(tag => tag.toLowerCase().includes(keyword)) ||
- complaint.keywordMatched?.some(kw => kw.toLowerCase().includes(keyword))
- );
- }
- return filtered;
- });
- // 获取投诉类型
- getComplaintType(complaint: any): string {
- if (complaint.type) return complaint.type;
-
- // 根据描述内容推断类型
- const description = complaint.description?.toLowerCase() || '';
- if (description.includes('质量') || description.includes('缺陷')) return 'quality';
- if (description.includes('服务') || description.includes('态度')) return 'service';
- if (description.includes('延期') || description.includes('时间')) return 'delivery';
- if (description.includes('沟通') || description.includes('联系')) return 'communication';
- if (description.includes('设计') || description.includes('效果')) return 'design';
-
- return 'other';
- }
- // 获取类型标签
- getTypeLabel(type: string): string {
- const typeObj = this.complaintTypes.find(t => t.value === type);
- return typeObj ? typeObj.label : '其他';
- }
- // 获取优先级信息
- getPriorityInfo(priority: string) {
- return this.priorities.find(p => p.value === priority) || this.priorities[0];
- }
- // 获取状态样式类
- getStatusClass(complaint: any): string {
- switch (complaint.status) {
- case '待处理': return 'pending';
- case '处理中': return 'processing';
- case '已解决': return 'resolved';
- default: return 'pending';
- }
- }
- // 获取优先级样式类
- getPriorityClass(priority: string): string {
- switch (priority) {
- case 'low': return 'priority-low';
- case 'medium': return 'priority-medium';
- case 'high': return 'priority-high';
- case 'urgent': return 'priority-urgent';
- default: return 'priority-low';
- }
- }
- // 获取处理天数(修复NaN问题)
- getDaysInProgress(complaint: ComplaintItem): number {
- if (!complaint.submittedAt) {
- return 0;
- }
-
- const submittedDate = new Date(complaint.submittedAt);
- const currentDate = complaint.resolvedAt ? new Date(complaint.resolvedAt) : new Date();
-
- // 检查日期是否有效
- if (isNaN(submittedDate.getTime()) || isNaN(currentDate.getTime())) {
- return 0;
- }
-
- const diffTime = Math.abs(currentDate.getTime() - submittedDate.getTime());
- const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
-
- return diffDays;
- }
- // 开始处理投诉
- startProcessing(complaint: ComplaintItem): void {
- // 更新投诉状态为处理中
- complaint.status = '处理中';
-
- // 可以在这里添加更多逻辑,比如分配处理人员等
- console.log('开始处理投诉:', complaint.id);
-
- // 这里可以调用服务来更新后端数据
- // this.complaintService.updateComplaintStatus(complaint.id, '处理中');
- }
- // 完成处理投诉
- completeProcessing(complaint: ComplaintItem): void {
- // 更新投诉状态为已解决
- complaint.status = '已解决';
- complaint.resolvedAt = new Date();
-
- // 可以在这里添加处理结果的逻辑
- console.log('完成处理投诉:', complaint.id);
-
- // 这里可以调用服务来更新后端数据
- // this.complaintService.completeComplaint(complaint.id, resolvedData);
- }
- // 查看投诉详情
- viewDetails(complaint: ComplaintItem): void {
- console.log('查看投诉详情:', complaint.id);
- this.selectedComplaint.set(complaint);
- this.showDetailModal.set(true);
- }
-
- // 关闭详情弹窗
- closeDetailModal(): void {
- this.showDetailModal.set(false);
- this.selectedComplaint.set(null);
- }
- // 判断是否超时
- isOverdue(complaint: any): boolean {
- if (complaint.status === '已解决') return false;
-
- const daysInProgress = this.getDaysInProgress(complaint);
- const maxDays = complaint.priority === 'urgent' ? 1 :
- complaint.priority === 'high' ? 3 :
- complaint.priority === 'medium' ? 7 : 14;
-
- return daysInProgress > maxDays;
- }
- // 更新筛选条件
- updateStatusFilter(status: string | any) {
- if (typeof status === 'string') {
- this.statusFilter.set(status);
- } else {
- this.statusFilter.set(status.target.value);
- }
- }
- updatePriorityFilter(event: any) {
- this.priorityFilter.set(event.target.value);
- }
- updateTypeFilter(event: any) {
- this.typeFilter.set(event.target.value);
- }
- updateSearchKeyword(keyword: string) {
- this.searchKeyword.set(keyword);
- }
- updateSourceFilter(event: any) {
- this.sourceFilter.set(event.target.value);
- }
- updateUrgencyFilter(event: any) {
- this.urgencyFilter.set(event.target.value);
- }
- // ==================== 新增投诉管理功能 ====================
- // 创建实时代办项
- createRealTimeTask(complaint: ComplaintItem): void {
- this.realTimeTaskStatus.set('processing');
- this.processingTaskId.set(complaint.id);
-
- console.log('创建实时代办项:', complaint.id);
-
- // 模拟异步处理
- setTimeout(() => {
- complaint.status = '处理中';
- complaint.assignedTo = '当前用户'; // 实际应该从用户服务获取
- this.realTimeTaskStatus.set('completed');
-
- // 这里可以调用服务来创建实时代办项
- // this.complaintService.createRealTimeTask(complaint);
- }, 2000);
- }
- // 企业微信自动获取投诉
- startWeChatMonitoring(): void {
- console.log('开始企业微信投诉监控');
-
- // 这里可以调用企业微信API服务
- // this.wechatService.startComplaintMonitoring(this.monitorKeywords);
-
- // 模拟自动获取到的投诉
- const autoComplaint: ComplaintItem = {
- id: 'wechat_' + Date.now(),
- type: 'service',
- description: '客户在微信群中表达不满意,提到"服务态度不好"',
- status: '待处理',
- source: 'wechat_auto',
- wechatGroupName: '项目交流群',
- wechatMessageId: 'msg_' + Date.now(),
- keywordMatched: ['不满意', '服务态度'],
- autoTagged: true,
- urgencyLevel: 'urgent',
- priority: 'high',
- submitTime: new Date(),
- submittedAt: new Date(),
- customerName: '张先生',
- followUpRequired: true,
- escalationLevel: 1
- };
-
- // 添加到投诉列表
- this.complaints.push(autoComplaint);
-
- alert('检测到新的微信投诉,已自动创建投诉记录');
- }
- // 设置关键词监控
- setupKeywordMonitoring(): void {
- console.log('设置关键词监控:', this.monitorKeywords);
-
- // 这里可以打开关键词设置弹窗
- const newKeywords = prompt('请输入监控关键词(用逗号分隔):', this.monitorKeywords.join(','));
-
- if (newKeywords) {
- this.monitorKeywords = newKeywords.split(',').map(k => k.trim()).filter(k => k);
- console.log('更新关键词监控:', this.monitorKeywords);
-
- // 这里可以调用服务更新关键词配置
- // this.complaintService.updateMonitorKeywords(this.monitorKeywords);
- }
- }
- // 分配投诉处理人
- assignComplaint(complaint: ComplaintItem, assignee: string): void {
- complaint.assignedTo = assignee;
- complaint.status = '处理中';
-
- console.log('分配投诉处理人:', complaint.id, '→', assignee);
-
- // 这里可以调用服务更新分配信息
- // this.complaintService.assignComplaint(complaint.id, assignee);
- }
- // 升级投诉
- escalateComplaint(complaint: ComplaintItem): void {
- if (!complaint.escalationLevel) {
- complaint.escalationLevel = 0;
- }
-
- if (complaint.escalationLevel < 3) {
- complaint.escalationLevel++;
- complaint.urgencyLevel = complaint.escalationLevel >= 2 ? 'critical' : 'urgent';
- complaint.priority = 'urgent';
-
- console.log('投诉升级:', complaint.id, '升级到级别', complaint.escalationLevel);
-
- // 这里可以调用服务处理升级逻辑
- // this.complaintService.escalateComplaint(complaint.id, complaint.escalationLevel);
- }
- }
- // 模拟从企业微信获取新投诉
- simulateNewWeChatComplaint(): void {
- const newComplaint: ComplaintItem = {
- id: 'wechat_' + Date.now(),
- type: 'quality',
- description: '客户在微信群中反映图纸质量问题,要求重新制作',
- submitTime: new Date(),
- submittedAt: new Date(),
- status: '待处理',
- customerName: '张先生',
- priority: 'urgent',
- source: 'wechat_auto',
- wechatGroupName: '项目交付群-张先生',
- wechatMessageId: 'msg_' + Date.now(),
- keywordMatched: ['质量差', '重新制作'],
- autoTagged: true,
- urgencyLevel: 'urgent',
- followUpRequired: true,
- relatedProjectId: 'proj_001',
- escalationLevel: 1,
- tags: ['质量问题', '微信投诉', '紧急处理']
- };
-
- // 添加到投诉列表
- this.complaints.push(newComplaint);
- console.log('检测到新的微信投诉:', newComplaint);
- }
- // 实时处理代办项
- processRealTimeTask(taskId: string): void {
- this.processingTaskId.set(taskId);
- this.realTimeTaskStatus.set('processing');
-
- console.log('开始处理实时代办项:', taskId);
-
- // 模拟处理过程
- setTimeout(() => {
- this.realTimeTaskStatus.set('completed');
- this.processingTaskId.set('');
- console.log('实时代办项处理完成');
- }, 3000);
- }
- // 通知升级
- notifyEscalation(complaint: ComplaintItem): void {
- console.log('发送升级通知:', complaint.id);
- // 这里可以实现邮件、短信或企业微信通知
- }
- // 设置预计解决时间
- setEstimatedResolutionTime(complaint: ComplaintItem, hours: number): void {
- const estimatedTime = new Date();
- estimatedTime.setHours(estimatedTime.getHours() + hours);
- complaint.estimatedResolutionTime = estimatedTime;
-
- console.log('设置预计解决时间:', complaint.id, estimatedTime);
- }
- // 客户满意度评分
- setCustomerSatisfaction(complaint: ComplaintItem, score: number): void {
- complaint.customerSatisfaction = Math.max(1, Math.min(5, score));
-
- console.log('客户满意度评分:', complaint.id, score);
- }
- // 批量处理投诉
- batchProcessComplaints(complaintIds: string[], action: string): void {
- console.log('批量处理投诉:', complaintIds, action);
-
- complaintIds.forEach(id => {
- const complaint = this.complaints.find(c => c.id === id);
- if (complaint) {
- switch (action) {
- case 'assign':
- // 批量分配
- break;
- case 'tag':
- // 批量添加标签
- break;
- case 'escalate':
- // 批量升级
- this.escalateComplaint(complaint);
- break;
- }
- }
- });
- }
- // 设置后续跟进
- setFollowUpRequired(complaint: ComplaintItem, required: boolean): void {
- complaint.followUpRequired = required;
-
- console.log('设置后续跟进:', complaint.id, '→', required);
-
- // 这里可以调用服务更新跟进状态
- // this.complaintService.setFollowUpRequired(complaint.id, required);
- }
- // 获取投诉来源信息
- getComplaintSourceInfo(complaint: ComplaintItem) {
- const source = this.complaintSources.find(s => s.value === complaint.source);
- return source || { value: 'manual', label: '人工创建', icon: '👥' };
- }
- // 获取紧急程度信息
- getUrgencyInfo(complaint: ComplaintItem) {
- const urgency = this.urgencyLevels.find(u => u.value === complaint.urgencyLevel);
- return urgency || { value: 'normal', label: '普通', color: '#52c41a' };
- }
- // 检查是否为自动标注
- isAutoTagged(complaint: ComplaintItem): boolean {
- return complaint.autoTagged === true;
- }
- // 获取升级级别显示
- getEscalationDisplay(level: number): string {
- const levels = ['普通', '一级', '二级', '三级'];
- return levels[level] || '普通';
- }
- // 确认客户评价完成
- confirmCustomerReviewComplete(complaint: ComplaintItem): void {
- // 更新投诉状态
- complaint.status = '已解决';
- complaint.resolvedAt = new Date();
-
- console.log('确认客户评价完成:', complaint.id);
-
- // 这里可以调用服务来更新后端数据
- // this.complaintService.confirmCustomerReview(complaint.id);
- }
- // 确认投诉解决完成
- confirmComplaintResolutionComplete(complaint: ComplaintItem): void {
- console.log('确认投诉解决完成:', complaint.id);
- // 这里可以添加确认投诉解决完成的逻辑
- // 例如:更新状态、发送通知等
- complaint.status = 'resolved';
- complaint.actualResolutionTime = new Date();
- }
- // 打开添加标签弹窗
- addComplaintTag(complaint: ComplaintItem, tag?: string): void {
- if (tag) {
- // 如果直接传入标签,直接添加
- if (!complaint.tags) {
- complaint.tags = [];
- }
- if (!complaint.tags.includes(tag)) {
- complaint.tags.push(tag);
- console.log(`为投诉 ${complaint.id} 添加标签: ${tag}`);
- }
- } else {
- // 否则打开标签弹窗
- this.tagModalComplaint.set(complaint);
- this.showTagModal.set(true);
- this.newTagInput.set('');
- }
- }
-
- // 关闭标签弹窗
- closeTagModal(): void {
- this.showTagModal.set(false);
- this.tagModalComplaint.set(null);
- this.newTagInput.set('');
- }
-
- // 选择预设标签
- selectPresetTag(tag: string): void {
- const complaint = this.tagModalComplaint();
- if (!complaint) return;
-
- if (!complaint.tags) {
- complaint.tags = [];
- }
-
- if (!complaint.tags.includes(tag)) {
- complaint.tags.push(tag);
- console.log(`为投诉 ${complaint.id} 添加预设标签: ${tag}`);
- }
- }
-
- // 添加自定义标签
- addCustomTag(): void {
- const complaint = this.tagModalComplaint();
- const newTag = this.newTagInput().trim();
-
- if (!complaint || !newTag) return;
-
- if (!complaint.tags) {
- complaint.tags = [];
- }
-
- if (!complaint.tags.includes(newTag)) {
- complaint.tags.push(newTag);
- console.log(`为投诉 ${complaint.id} 添加自定义标签: ${newTag}`);
- this.newTagInput.set('');
- }
- }
-
- // 移除标签
- removeTag(complaint: ComplaintItem, tag: string): void {
- if (!complaint.tags) return;
-
- const index = complaint.tags.indexOf(tag);
- if (index > -1) {
- complaint.tags.splice(index, 1);
- console.log(`从投诉 ${complaint.id} 移除标签: ${tag}`);
- }
- }
- }
|