|
@@ -1,6 +1,31 @@
|
|
|
-import { Component } from '@angular/core';
|
|
|
+// src/app/pages/page-crm-image/page-crm-image.ts
|
|
|
+
|
|
|
+import { Component, AfterViewInit, ElementRef, ViewChild, OnInit } from '@angular/core';
|
|
|
import { CommonModule } from '@angular/common';
|
|
|
import { FormsModule } from '@angular/forms';
|
|
|
+import Chart from 'chart.js/auto';
|
|
|
+import { CRMServices, Client, ChatMessage } from './crm-service'; // 导入新的服务和模型
|
|
|
+
|
|
|
+// 定义推荐项类型
|
|
|
+interface Recommendation {
|
|
|
+ icon: string;
|
|
|
+ title: string;
|
|
|
+ content: string;
|
|
|
+ tag: string;
|
|
|
+ buttonText: string;
|
|
|
+ iconColor: string;
|
|
|
+ iconTextColor: string;
|
|
|
+}
|
|
|
+
|
|
|
+// 定义分析结果类型
|
|
|
+interface AnalysisResult {
|
|
|
+ gender?: string;
|
|
|
+ age?: string;
|
|
|
+ job?: string;
|
|
|
+ psychology?: string;
|
|
|
+ consumption?: string;
|
|
|
+ needs?: string;
|
|
|
+}
|
|
|
|
|
|
@Component({
|
|
|
selector: 'app-page-crm-image',
|
|
@@ -9,25 +34,25 @@ import { FormsModule } from '@angular/forms';
|
|
|
templateUrl: './page-crm-image.html',
|
|
|
styleUrls: ['./page-crm-image.scss']
|
|
|
})
|
|
|
-export class PageCrmImage {
|
|
|
+export class PageCrmImage implements AfterViewInit, OnInit {
|
|
|
// 表单数据
|
|
|
clientId = '';
|
|
|
clientName = '';
|
|
|
chatData = '';
|
|
|
searchTerm = '';
|
|
|
reportName = '';
|
|
|
+ clientType = '企业客户';
|
|
|
|
|
|
// 弹窗控制
|
|
|
showBaseReportModal = false;
|
|
|
showChatDetailModal = false;
|
|
|
showAnalysisResultModal = false;
|
|
|
+ isLoading = false;
|
|
|
+ loadingMessage = '';
|
|
|
|
|
|
// 当前日期
|
|
|
currentDate = new Date();
|
|
|
|
|
|
- // 客户数据
|
|
|
- clientType = '企业客户';
|
|
|
-
|
|
|
// 聊天记录详情
|
|
|
chatDetail = {
|
|
|
date: '2023-07-15 14:30',
|
|
@@ -35,7 +60,7 @@ export class PageCrmImage {
|
|
|
};
|
|
|
|
|
|
// 分析结果
|
|
|
- analysisResult = {
|
|
|
+ analysisResult: AnalysisResult = {
|
|
|
gender: '男',
|
|
|
age: '35-40岁',
|
|
|
job: 'IT经理',
|
|
@@ -44,16 +69,35 @@ export class PageCrmImage {
|
|
|
needs: '需要高效解决方案'
|
|
|
};
|
|
|
|
|
|
+ // 图表数据
|
|
|
+ chartData = {
|
|
|
+ labels: ['理性决策', '价格敏感', '品牌忠诚', '冒险尝试', '社交导向'],
|
|
|
+ datasets: [{
|
|
|
+ label: '客户心理特征分析',
|
|
|
+ data: [75, 40, 30, 20, 55],
|
|
|
+ backgroundColor: [
|
|
|
+ 'rgba(74, 143, 231, 0.7)',
|
|
|
+ 'rgba(94, 114, 228, 0.7)',
|
|
|
+ 'rgba(23, 162, 184, 0.7)',
|
|
|
+ 'rgba(255, 99, 132, 0.7)',
|
|
|
+ 'rgba(54, 162, 235, 0.7)'
|
|
|
+ ],
|
|
|
+ borderColor: [
|
|
|
+ 'rgb(74, 143, 231)',
|
|
|
+ 'rgb(94, 114, 228)',
|
|
|
+ 'rgb(23, 162, 184)',
|
|
|
+ 'rgb(255, 99, 132)',
|
|
|
+ 'rgb(54, 162, 235)'
|
|
|
+ ],
|
|
|
+ borderWidth: 1
|
|
|
+ }]
|
|
|
+ };
|
|
|
+
|
|
|
// 客户列表
|
|
|
- clients = [
|
|
|
- { id: 'C1001', name: '张明远', type: '企业客户', date: '06-28' },
|
|
|
- { id: 'P2003', name: '李思琪', type: '个人客户', date: '06-27' },
|
|
|
- { id: 'C1002', name: '王建国', type: '企业客户', date: '06-25' },
|
|
|
- { id: 'P2004', name: '陈晓薇', type: '个人客户', date: '06-24' }
|
|
|
- ];
|
|
|
-
|
|
|
+ clients: Client[] = [];
|
|
|
+
|
|
|
// 推荐数据
|
|
|
- recommendations = [
|
|
|
+ recommendations: Recommendation[] = [
|
|
|
{
|
|
|
icon: 'fas fa-user-friends',
|
|
|
title: '相似客户推荐',
|
|
@@ -73,58 +117,316 @@ export class PageCrmImage {
|
|
|
iconTextColor: '#5e72e4'
|
|
|
}
|
|
|
];
|
|
|
-
|
|
|
+
|
|
|
+ // 格式化后的聊天消息
|
|
|
+ formattedChatMessages: ChatMessage[] = [];
|
|
|
+
|
|
|
+ @ViewChild('analysisChart', { static: false }) analysisChartRef: ElementRef | undefined;
|
|
|
+ private analysisChart: Chart | undefined;
|
|
|
+
|
|
|
+ constructor(private crmService: CRMServices) {
|
|
|
+ // 从后端加载客户数据
|
|
|
+ this.loadClientsFromBackend();
|
|
|
+ }
|
|
|
+
|
|
|
+ ngOnInit() {
|
|
|
+ // 初始化时格式化聊天记录
|
|
|
+ this.formatChatMessages();
|
|
|
+ }
|
|
|
+
|
|
|
+ ngAfterViewInit() {
|
|
|
+ this.createAnalysisChart();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取过滤后的客户列表
|
|
|
+ get filteredClients() {
|
|
|
+ if (!this.searchTerm) return this.clients;
|
|
|
+
|
|
|
+ const term = this.searchTerm.toLowerCase();
|
|
|
+ return this.clients.filter(client =>
|
|
|
+ client.get('clientName')?.toLowerCase().includes(term) ||
|
|
|
+ client.get('clientId')?.toLowerCase().includes(term)
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ // 从后端加载客户数据
|
|
|
+ async loadClientsFromBackend() {
|
|
|
+ this.showLoading('正在加载客户数据...');
|
|
|
+
|
|
|
+ try {
|
|
|
+ const clients = await this.crmService.getAllClients();
|
|
|
+ this.clients = clients;
|
|
|
+ } catch (error) {
|
|
|
+ console.error('加载客户数据失败', error);
|
|
|
+ alert('加载客户数据失败,请稍后再试');
|
|
|
+ } finally {
|
|
|
+ this.hideLoading();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 格式化聊天记录
|
|
|
+ formatChatMessages() {
|
|
|
+ this.formattedChatMessages = [];
|
|
|
+
|
|
|
+ if (!this.chatData) return;
|
|
|
+
|
|
|
+ // 假设聊天记录格式为:[时间] 发送者: 消息内容
|
|
|
+ const chatRegex = /\[([^\]]+)\]\s*([^:]+):\s*(.+)/g;
|
|
|
+ let match;
|
|
|
+
|
|
|
+ while ((match = chatRegex.exec(this.chatData)) !== null) {
|
|
|
+ const msg = new ChatMessage();
|
|
|
+ msg.setMessageData({
|
|
|
+ clientId: this.clientId,
|
|
|
+ time: match[1],
|
|
|
+ sender: match[2],
|
|
|
+ content: match[3]
|
|
|
+ });
|
|
|
+ this.formattedChatMessages.push(msg);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果没有匹配到特定格式,创建一个默认消息
|
|
|
+ if (this.formattedChatMessages.length === 0 && this.chatData.trim()) {
|
|
|
+ const msg = new ChatMessage();
|
|
|
+ msg.setMessageData({
|
|
|
+ clientId: this.clientId,
|
|
|
+ time: new Date().toLocaleTimeString(),
|
|
|
+ sender: '系统',
|
|
|
+ content: this.chatData
|
|
|
+ });
|
|
|
+ this.formattedChatMessages.push(msg);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 创建分析图表
|
|
|
+ createAnalysisChart() {
|
|
|
+ if (this.analysisChartRef) {
|
|
|
+ const ctx = this.analysisChartRef.nativeElement.getContext('2d');
|
|
|
+ if (ctx) {
|
|
|
+ this.analysisChart = new Chart(ctx, {
|
|
|
+ type: 'radar',
|
|
|
+ data: this.chartData,
|
|
|
+ options: {
|
|
|
+ scales: {
|
|
|
+ r: {
|
|
|
+ angleLines: {
|
|
|
+ display: true
|
|
|
+ },
|
|
|
+ suggestedMin: 0,
|
|
|
+ suggestedMax: 100
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
// 保存分析
|
|
|
- save() {
|
|
|
+ async save() {
|
|
|
if (!this.clientId || !this.clientName || !this.chatData) {
|
|
|
alert('请填写完整的客户信息和聊天记录');
|
|
|
return;
|
|
|
}
|
|
|
- this.showBaseReportModal = true;
|
|
|
+
|
|
|
+ // 格式化聊天记录
|
|
|
+ this.formatChatMessages();
|
|
|
+
|
|
|
+ // 保存到后端
|
|
|
+ this.showLoading('正在保存客户信息...');
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 保存客户数据
|
|
|
+ await this.crmService.saveClient({
|
|
|
+ clientId: this.clientId,
|
|
|
+ clientName: this.clientName,
|
|
|
+ clientType: this.clientType,
|
|
|
+ chatData: this.chatData,
|
|
|
+ date: new Date().toLocaleDateString()
|
|
|
+ });
|
|
|
+
|
|
|
+ // 保存聊天消息
|
|
|
+ await this.crmService.saveChatMessages(this.clientId, this.formattedChatMessages);
|
|
|
+
|
|
|
+ // 刷新客户列表
|
|
|
+ await this.loadClientsFromBackend();
|
|
|
+
|
|
|
+ this.hideLoading();
|
|
|
+ this.showBaseReportModal = true;
|
|
|
+ } catch (error) {
|
|
|
+ console.error('保存客户数据失败', error);
|
|
|
+ alert('保存客户数据失败,请稍后再试');
|
|
|
+ this.hideLoading();
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 开始分析
|
|
|
- analyze() {
|
|
|
+ async analyze() {
|
|
|
if (!this.clientId || !this.clientName || !this.chatData) {
|
|
|
alert('请填写完整的客户信息和聊天记录');
|
|
|
return;
|
|
|
}
|
|
|
- alert(`开始分析客户 ${this.clientName} (${this.clientId}) 的聊天记录...`);
|
|
|
+
|
|
|
+ // 格式化聊天记录
|
|
|
+ this.formatChatMessages();
|
|
|
+
|
|
|
+ // 模拟分析过程
|
|
|
+ this.showLoading('正在分析客户数据...');
|
|
|
+
|
|
|
+ setTimeout(() => {
|
|
|
+ // 模拟分析结果
|
|
|
+ this.analysisResult = {
|
|
|
+ gender: Math.random() > 0.5 ? '男' : '女',
|
|
|
+ age: `${Math.floor(Math.random() * 20) + 25}-${Math.floor(Math.random() * 5) + 30}岁`,
|
|
|
+ job: ['IT经理', '市场营销', '金融分析师', '教师', '医生'][Math.floor(Math.random() * 5)],
|
|
|
+ psychology: ['理性决策型', '冲动消费型', '品牌忠诚型', '社交导向型'][Math.floor(Math.random() * 4)],
|
|
|
+ consumption: ['注重性价比', '高端消费', '中等消费', '价格敏感型'][Math.floor(Math.random() * 4)],
|
|
|
+ needs: ['需要高效解决方案', '寻求价格优惠', '追求品质体验', '关注品牌价值'][Math.floor(Math.random() * 4)]
|
|
|
+ };
|
|
|
+
|
|
|
+ // 更新图表数据
|
|
|
+ this.chartData.datasets[0].data = [
|
|
|
+ Math.floor(Math.random() * 40) + 60, // 理性决策
|
|
|
+ Math.floor(Math.random() * 80) + 20, // 价格敏感
|
|
|
+ Math.floor(Math.random() * 70) + 30, // 品牌忠诚
|
|
|
+ Math.floor(Math.random() * 50) + 10, // 冒险尝试
|
|
|
+ Math.floor(Math.random() * 70) + 30 // 社交导向
|
|
|
+ ];
|
|
|
+
|
|
|
+ if (this.analysisChart) {
|
|
|
+ this.analysisChart.data = this.chartData;
|
|
|
+ this.analysisChart.update();
|
|
|
+ }
|
|
|
+
|
|
|
+ this.hideLoading();
|
|
|
+ alert(`客户 ${this.clientName} (${this.clientId}) 分析完成!`);
|
|
|
+ }, 2000);
|
|
|
}
|
|
|
-
|
|
|
- // 打开聊天详情弹窗
|
|
|
- openChatDetailModal() {
|
|
|
- this.showBaseReportModal = false;
|
|
|
- this.showChatDetailModal = true;
|
|
|
+
|
|
|
+ // 导出报告
|
|
|
+ exportReport() {
|
|
|
+ this.showLoading('正在生成报告...');
|
|
|
+
|
|
|
+ setTimeout(() => {
|
|
|
+ this.hideLoading();
|
|
|
+ alert('报告已成功导出!');
|
|
|
+ }, 1500);
|
|
|
}
|
|
|
-
|
|
|
- // 打开分析结果弹窗
|
|
|
- openAnalysisResultModal() {
|
|
|
- this.showBaseReportModal = false;
|
|
|
- this.showAnalysisResultModal = true;
|
|
|
+
|
|
|
+ // 加载客户数据
|
|
|
+ async loadClient(client: Client) {
|
|
|
+ this.clientId = client.get('clientId');
|
|
|
+ this.clientName = client.get('clientName');
|
|
|
+ this.clientType = client.get('clientType');
|
|
|
+ this.chatData = client.get('chatData');
|
|
|
+
|
|
|
+ // 从后端加载聊天记录
|
|
|
+ this.showLoading('正在加载客户数据...');
|
|
|
+
|
|
|
+ try {
|
|
|
+ const messages = await this.crmService.getChatMessages(this.clientId);
|
|
|
+ this.formattedChatMessages = messages;
|
|
|
+
|
|
|
+ this.hideLoading();
|
|
|
+ this.showBaseReportModal = true;
|
|
|
+ } catch (error) {
|
|
|
+ console.error('加载聊天记录失败', error);
|
|
|
+ alert('加载聊天记录失败,请稍后再试');
|
|
|
+ this.hideLoading();
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
- // 打开推荐策略弹窗
|
|
|
- openStrategyModal() {
|
|
|
- alert('推荐策略功能开发中...');
|
|
|
+
|
|
|
+ // 删除客户
|
|
|
+ async deleteClient(clientId: string, event: Event) {
|
|
|
+ event.stopPropagation(); // 阻止事件冒泡
|
|
|
+
|
|
|
+ if (confirm('确定要删除这个客户记录吗?')) {
|
|
|
+ this.showLoading('正在删除客户数据...');
|
|
|
+
|
|
|
+ try {
|
|
|
+ await this.crmService.deleteClient(clientId);
|
|
|
+ // 刷新客户列表
|
|
|
+ await this.loadClientsFromBackend();
|
|
|
+ this.hideLoading();
|
|
|
+ } catch (error) {
|
|
|
+ console.error('删除客户失败', error);
|
|
|
+ alert('删除客户失败,请稍后再试');
|
|
|
+ this.hideLoading();
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
- // 返回基础弹窗
|
|
|
+
|
|
|
+ // 清空所有客户
|
|
|
+ async clearAllClients() {
|
|
|
+ if (confirm('确定要清空所有客户记录吗?此操作不可撤销!')) {
|
|
|
+ this.showLoading('正在清空客户数据...');
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 逐个删除客户
|
|
|
+ for (const client of this.clients) {
|
|
|
+ await this.crmService.deleteClient(client.get('clientId'));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 刷新客户列表
|
|
|
+ this.clients = [];
|
|
|
+ this.hideLoading();
|
|
|
+ } catch (error) {
|
|
|
+ console.error('清空客户数据失败', error);
|
|
|
+ alert('清空客户数据失败,请稍后再试');
|
|
|
+ this.hideLoading();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 刷新客户列表
|
|
|
+ async refreshClients() {
|
|
|
+ await this.loadClientsFromBackend();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 显示加载中状态
|
|
|
+ showLoading(message: string) {
|
|
|
+ this.loadingMessage = message;
|
|
|
+ this.isLoading = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 隐藏加载中状态
|
|
|
+ hideLoading() {
|
|
|
+ this.isLoading = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 关闭模态框
|
|
|
+ closeModal() {
|
|
|
+ this.showBaseReportModal = false;
|
|
|
+ this.showChatDetailModal = false;
|
|
|
+ this.showAnalysisResultModal = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 返回基础报告模态框
|
|
|
backToBaseModal() {
|
|
|
this.showChatDetailModal = false;
|
|
|
this.showAnalysisResultModal = false;
|
|
|
this.showBaseReportModal = true;
|
|
|
}
|
|
|
-
|
|
|
- // 关闭所有弹窗
|
|
|
- closeModal() {
|
|
|
+
|
|
|
+ // 打开聊天详情模态框
|
|
|
+ openChatDetailModal() {
|
|
|
this.showBaseReportModal = false;
|
|
|
- this.showChatDetailModal = false;
|
|
|
- this.showAnalysisResultModal = false;
|
|
|
+ this.showChatDetailModal = true;
|
|
|
}
|
|
|
-
|
|
|
- // 客户点击事件
|
|
|
- onClientClick(client: any) {
|
|
|
- alert(`进入客户详情页:${client.name}`);
|
|
|
+
|
|
|
+ // 打开分析结果模态框
|
|
|
+ openAnalysisResultModal() {
|
|
|
+ this.showBaseReportModal = false;
|
|
|
+ this.showAnalysisResultModal = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 打开策略模态框(假设实现)
|
|
|
+ openStrategyModal() {
|
|
|
+ alert('推荐策略功能将在未来版本中实现');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理推荐项点击
|
|
|
+ handleRecommendationAction(recommendation: Recommendation) {
|
|
|
+ alert(`执行推荐操作: ${recommendation.title}`);
|
|
|
}
|
|
|
}
|