|
|
@@ -0,0 +1,2305 @@
|
|
|
+<template>
|
|
|
+ <div class="customer-container">
|
|
|
+ <div class="main-grid-three-columns">
|
|
|
+ <div class="left-column">
|
|
|
+ <!-- 客户画像 (成交要素) -->
|
|
|
+ <div class="card">
|
|
|
+ <div class="card-header">
|
|
|
+ <h3><i class="fas fa-id-card"></i> 客户画像(成交要素)</h3>
|
|
|
+ </div>
|
|
|
+ <div class="profile-grid">
|
|
|
+ <div class="profile-item profile-item-main">
|
|
|
+ <span class="label"><i class="fas fa-user"></i> 客户姓名:</span>
|
|
|
+ <span class="value highlight">{{ (customerData && (customerData.customerName || customerData.name)) || '-' }}</span>
|
|
|
+ </div>
|
|
|
+ <template v-for="(value, key) in customerPortraitData">
|
|
|
+ <div
|
|
|
+ v-if="key !== '需求'"
|
|
|
+ :key="key"
|
|
|
+ class="profile-item"
|
|
|
+ >
|
|
|
+ <span class="label">
|
|
|
+ <i class="fas fa-info-circle"></i> {{ key }}:
|
|
|
+ </span>
|
|
|
+ <span class="value">{{ value }}</span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <!-- 需求单独显示,占满整行 -->
|
|
|
+ <div
|
|
|
+ v-if="customerPortraitData['需求']"
|
|
|
+ key="需求"
|
|
|
+ class="profile-item profile-item-full"
|
|
|
+ >
|
|
|
+ <span class="label">
|
|
|
+ <i class="fas fa-bullseye"></i> 需求:
|
|
|
+ </span>
|
|
|
+ <span class="value long-text">{{ customerPortraitData['需求'] }}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- AI 标签 -->
|
|
|
+ <div class="card">
|
|
|
+ <div class="card-header">
|
|
|
+ <h3>
|
|
|
+ <i class="fas fa-tags"></i> AI 标签
|
|
|
+ </h3>
|
|
|
+ <!-- <el-button
|
|
|
+ v-if="allAiTags.length === 0"
|
|
|
+ size="mini"
|
|
|
+ type="primary"
|
|
|
+ @click="handleAnalyzeTag"
|
|
|
+ >
|
|
|
+ AI分析标签
|
|
|
+ </el-button> -->
|
|
|
+ </div>
|
|
|
+ <div class="tags-container">
|
|
|
+ <div v-if="allAiTags.length > 0" class="tags-list">
|
|
|
+ <div
|
|
|
+ v-for="(item, index) in visibleTags"
|
|
|
+ :key="item.id"
|
|
|
+ class="tag-item"
|
|
|
+ :class="{ 'tag-highlight': index < 3 }"
|
|
|
+ >
|
|
|
+ <span class="tag-key">{{ item.propertyName }}</span>
|
|
|
+ <span class="tag-separator">:</span>
|
|
|
+ <span class="tag-value">{{ item.propertyValue }}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div v-else class="empty-tags">
|
|
|
+ <i class="fas fa-inbox"></i>
|
|
|
+ <span>暂无 AI 标签</span>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 加载更多按钮 -->
|
|
|
+ <div v-if="allAiTags.length > tagsPageSize" class="tags-actions">
|
|
|
+ <button
|
|
|
+ v-if="!isExpanded"
|
|
|
+ @click="loadMoreTags"
|
|
|
+ class="btn-expand-tags"
|
|
|
+ type="button"
|
|
|
+ >
|
|
|
+ <i class="fas fa-chevron-down"></i> 展开全部 ({{ allAiTags.length - tagsPageSize }})
|
|
|
+ </button>
|
|
|
+
|
|
|
+ <!-- 收起按钮 -->
|
|
|
+ <button
|
|
|
+ v-else
|
|
|
+ @click="collapseTags"
|
|
|
+ class="btn-collapse-tags"
|
|
|
+ type="button"
|
|
|
+ >
|
|
|
+ <i class="fas fa-chevron-up"></i> 收起标签
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="middle-column">
|
|
|
+ <!-- 沟通摘要 -->
|
|
|
+ <div class="card">
|
|
|
+ <div class="card-header">
|
|
|
+ <h3><i class="fas fa-comment-dots"></i> 沟通摘要</h3>
|
|
|
+ </div>
|
|
|
+ <div class="summary-text compact">
|
|
|
+ {{ getCommunicationAbstract() }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- AI 沟通总结 -->
|
|
|
+ <div class="card">
|
|
|
+ <div class="card-header">
|
|
|
+ <h3><i class="fas fa-robot"></i> AI 沟通总结</h3>
|
|
|
+ </div>
|
|
|
+ <div class="summary-text compact">
|
|
|
+ {{ getCommunicationSummary() }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- 沟通记录 -->
|
|
|
+ <div class="card card-table">
|
|
|
+ <div class="card-header">
|
|
|
+ <h3><i class="fas fa-history"></i> 沟通记录</h3>
|
|
|
+ </div>
|
|
|
+ <div class="records-table-wrapper">
|
|
|
+ <table class="records-table">
|
|
|
+ <thead>
|
|
|
+ <tr>
|
|
|
+ <th><i class="fas fa-user"></i> 客户名称</th>
|
|
|
+ <th><i class="fas fa-chart-line"></i> 流失等级</th>
|
|
|
+ <th><i class="fas fa-heart"></i> 客户意向度</th>
|
|
|
+ <th><i class="far fa-clock"></i> 创建时间</th>
|
|
|
+ <th><i class="fas fa-cog"></i> 操作</th>
|
|
|
+ </tr>
|
|
|
+ </thead>
|
|
|
+ <tbody>
|
|
|
+ <tr v-for="record in communicationRecords" :key="record.id" class="record-row">
|
|
|
+ <td class="record-cell">{{ (customerData && (customerData.customerName || customerData.name)) || '-' }}</td>
|
|
|
+ <td class="record-cell">
|
|
|
+ <span class="risk-level-tag" :class="getRecordRiskLevelClass(record)">
|
|
|
+ {{ getRecordRiskLevelLabel(record) }}
|
|
|
+ </span>
|
|
|
+ </td>
|
|
|
+ <td class="record-cell">
|
|
|
+ <span class="intention-degree">
|
|
|
+ {{ getIntentionDegreeFromRecord(record) }}
|
|
|
+ </span>
|
|
|
+ </td>
|
|
|
+ <td class="record-cell">{{ parseTime(record.createTime, '{y}-{m}-{d} {h}:{i}:{s}') || '-' }}</td>
|
|
|
+ <td class="record-cell">
|
|
|
+ <button @click="viewChat(record)" class="btn-view-chat">
|
|
|
+ <i class="fas fa-comments"></i> 聊天详情
|
|
|
+ </button>
|
|
|
+ </td>
|
|
|
+ </tr>
|
|
|
+ <tr v-if="!communicationRecords.length">
|
|
|
+ <td colspan="5" class="empty-tip">
|
|
|
+ <i class="fas fa-inbox"></i> 暂无沟通记录
|
|
|
+ </td>
|
|
|
+ </tr>
|
|
|
+ </tbody>
|
|
|
+ </table>
|
|
|
+
|
|
|
+ <!-- 分页组件 -->
|
|
|
+ <div class="pagination-container" v-if="communicationRecordsTotal > 0">
|
|
|
+ <el-pagination
|
|
|
+ @current-change="handleCommunicationRecordsPageChange"
|
|
|
+ @size-change="handleCommunicationRecordsSizeChange"
|
|
|
+ :current-page="communicationRecordsPageNum"
|
|
|
+ :page-sizes="[4, 10, 20, 50]"
|
|
|
+ :page-size="communicationRecordsPageSize"
|
|
|
+ layout="total, sizes, prev, pager, next, jumper"
|
|
|
+ :total="communicationRecordsTotal"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- 微信风格聊天弹窗 -->
|
|
|
+ <div v-if="chatDialogVisible" class="chat-dialog-overlay" @click.self="closeChatDialog">
|
|
|
+ <div class="chat-dialog">
|
|
|
+ <div class="chat-dialog-header">
|
|
|
+ <div class="chat-title">
|
|
|
+ <i class="fas fa-comments"></i>
|
|
|
+ <span>{{
|
|
|
+ (currentChatRecord && currentChatRecord.customerName) || (customerData && customerData.customerName)
|
|
|
+ }} - 历史聊天记录</span>
|
|
|
+ </div>
|
|
|
+ <button @click="closeChatDialog" class="btn-close">
|
|
|
+ ×
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ <div class="chat-dialog-body">
|
|
|
+ <div class="chat-messages">
|
|
|
+ <!-- 根据 aiChatRecord 数组循环显示聊天记录 -->
|
|
|
+ <div
|
|
|
+ v-for="(msg, index) in parseChatMessages(currentChatRecord && currentChatRecord.aiChatRecord)"
|
|
|
+ :key="index"
|
|
|
+ class="message-item"
|
|
|
+ :class="msg.type === 'ai' ? 'message-left' : 'message-right'"
|
|
|
+ >
|
|
|
+ <!-- AI 消息:头像在左,名称在聊天内容上方靠左 -->
|
|
|
+ <div v-if="msg.type === 'ai'" class="message-wrapper message-wrapper-left">
|
|
|
+ <div class="message-avatar message-avatar-ai">
|
|
|
+ <img src="/static/images/ai-avatar.svg" alt="AI"
|
|
|
+ @error="handleAvatarError($event, 'ai')"/>
|
|
|
+ </div>
|
|
|
+ <div class="message-content">
|
|
|
+ <div class="message-name message-name-ai">AI</div>
|
|
|
+ <div class="message-bubble">
|
|
|
+ {{ msg.content }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 客户消息:强制头像在右侧 -->
|
|
|
+ <div v-else class="message-item message-item-customer">
|
|
|
+ <div class="message-content-right">
|
|
|
+ <div class="message-bubble message-bubble-right">
|
|
|
+ {{ msg.content }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="message-avatar message-avatar-customer">
|
|
|
+ <img src="/static/images/customer-avatar.svg" alt="客户"
|
|
|
+ @error="handleAvatarError($event, 'customer')"/>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 空数据提示 -->
|
|
|
+ <div
|
|
|
+ v-if="!parseChatMessages(currentChatRecord && currentChatRecord.aiChatRecord).length"
|
|
|
+ class="empty-chat-tip">
|
|
|
+ <i class="fas fa-inbox"></i> 暂无聊天内容
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 流失风险等级 + 客户关注点 & 意向度 -->
|
|
|
+ <div class="right-column">
|
|
|
+ <!-- 流失风险等级 -->
|
|
|
+ <div class="card risk-card" :class="getRiskLevelClass()">
|
|
|
+ <div class="card-header">
|
|
|
+ <h3><i class="fas fa-chart-line"></i> 流失风险等级</h3>
|
|
|
+ <span class="risk-badge" :class="getRiskLevelBadgeClass()">{{ getRiskLevelLabel() }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="risk-analysis">
|
|
|
+ <p class="risk-text">{{ getRiskLevelAnalysis() }}</p>
|
|
|
+ <div class="risk-tip" v-if="getRiskLevelTip()">
|
|
|
+ <i class="fas fa-exclamation-triangle"></i> {{ getRiskLevelTip() }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- 客户关注点 & 意向度 -->
|
|
|
+ <div class="card card-focus">
|
|
|
+ <div class="card-header">
|
|
|
+ <h3><i class="fas fa-lightbulb"></i> 客户关注点 & 意向度</h3>
|
|
|
+ </div>
|
|
|
+ <div class="focus-points">
|
|
|
+ <div class="focus-title">
|
|
|
+ <i class="fas fa-search"></i> 核心关注点:
|
|
|
+ </div>
|
|
|
+ <ul class="focus-list">
|
|
|
+ <li class="focus-item">{{customerFocusPoints}}</li>
|
|
|
+ <i class="fas fa-dot-circle"></i> {{ point }}
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ </div>
|
|
|
+ <div class="intention-section">
|
|
|
+ <div class="intention-header">
|
|
|
+ <span class="intention-label">客户意向度</span>
|
|
|
+ <el-tooltip placement="top" effect="light">
|
|
|
+ <i class="el-icon-info intention-info-icon"></i>
|
|
|
+ <div slot="content" class="intention-tooltip">
|
|
|
+ <div><strong>A 级</strong> - 最高意向度</div>
|
|
|
+ <div><strong>B 级</strong> - 高意向度</div>
|
|
|
+ <div><strong>C 级</strong> - 中等意向度</div>
|
|
|
+ <div><strong>D 级</strong> - 较低意向度</div>
|
|
|
+ <div><strong>E 级</strong> - 低意向度</div>
|
|
|
+ <div><strong>F 级</strong> - 最低意向度</div>
|
|
|
+ </div>
|
|
|
+ </el-tooltip>
|
|
|
+ </div>
|
|
|
+ <div class="intention-watermark"
|
|
|
+ v-if="getIntentionDegree()"
|
|
|
+ :class="getIntentionColorClass(getIntentionDegree())">
|
|
|
+ {{ getIntentionDegree() }}
|
|
|
+ </div>
|
|
|
+ <div class="no-intention-tip" v-else>
|
|
|
+ 暂无评级
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <el-dialog
|
|
|
+ title="AI分析标签"
|
|
|
+ :visible.sync="analyzeTagDialogVisible"
|
|
|
+ width="420px"
|
|
|
+ append-to-body
|
|
|
+ >
|
|
|
+ <el-form label-width="90px">
|
|
|
+ <el-form-item label="行业类型">
|
|
|
+ <el-select
|
|
|
+ v-model="selectedTradeType"
|
|
|
+ placeholder="请选择行业类型"
|
|
|
+ clearable
|
|
|
+ style="width: 100%;"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in tradeTypeOptions"
|
|
|
+ :key="item.dictValue"
|
|
|
+ :label="item.dictLabel"
|
|
|
+ :value="item.dictValue"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <div slot="footer" class="dialog-footer">
|
|
|
+ <el-button @click="analyzeTagDialogVisible = false">取 消</el-button>
|
|
|
+ <el-button type="primary" :loading="analyzeTagSubmitting" @click="confirmAnalyzeTag">确 定</el-button>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+ </div>
|
|
|
+
|
|
|
+
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+
|
|
|
+import {listByCustomerId,analyzeAiTagByTrade} from "../../../api/qw/customerProperty";
|
|
|
+import {listAnalyze} from "../../../api/qw/qwAnalyze";
|
|
|
+
|
|
|
+export default {
|
|
|
+ props: {
|
|
|
+ // 抽屉模式参数(父组件传入)
|
|
|
+ analyzeUserId: {
|
|
|
+ type: [String, Number],
|
|
|
+ default: null
|
|
|
+ },
|
|
|
+ analyzeExternalUserId: {
|
|
|
+ type: String,
|
|
|
+ default: null
|
|
|
+ },
|
|
|
+ analyzeCorpId: {
|
|
|
+ type: String,
|
|
|
+ default: null
|
|
|
+ },
|
|
|
+ customerRow: {
|
|
|
+ type: Object,
|
|
|
+ default: null
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ userId: null,
|
|
|
+ externalUserId: null,
|
|
|
+ corpId: null,
|
|
|
+ customerData: null, // 从列表页传递过来的完整客户数据
|
|
|
+ aiTags: [],// 需要显示的 AI 标签
|
|
|
+ allAiTags: [], // 存储所有 AI 标签
|
|
|
+ tagsPageSize: 5,//默认展开标签的数量
|
|
|
+ isExpanded: false, // 是否已展开显示全部标签
|
|
|
+ // 聊天记录分页相关
|
|
|
+ communicationRecords: [],
|
|
|
+ communicationRecordsTotal: 0,
|
|
|
+ communicationRecordsPageNum: 1,
|
|
|
+ communicationRecordsPageSize: 4,
|
|
|
+ // 聊天弹窗相关
|
|
|
+ chatDialogVisible: false, // 聊天弹窗是否显示
|
|
|
+ currentChatRecord: null, // 当前查看的聊天记录
|
|
|
+ analyzeTagDialogVisible: false,
|
|
|
+ analyzeTagSubmitting: false,
|
|
|
+ selectedTradeType: null,
|
|
|
+ tradeTypeOptions:[],
|
|
|
+ }
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ // 根据是否展开控制显示的标签数量
|
|
|
+ visibleTags() {
|
|
|
+ if (this.isExpanded) {
|
|
|
+ return this.allAiTags;
|
|
|
+ } else {
|
|
|
+ // 未展开时只显示前 3 条
|
|
|
+ return this.allAiTags.slice(0, this.tagsPageSize);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 客户画像数据(从最新的沟通记录中获取)
|
|
|
+ customerPortraitData() {
|
|
|
+ if (!this.communicationRecords || this.communicationRecords.length === 0) {
|
|
|
+ return {};
|
|
|
+ }
|
|
|
+ // 获取最新的沟通记录
|
|
|
+ const latestRecord = this.communicationRecords[0];
|
|
|
+ if (latestRecord && latestRecord.customerPortraitJson) {
|
|
|
+ try {
|
|
|
+ // 如果是字符串,解析为 JSON 对象
|
|
|
+ if (typeof latestRecord.customerPortraitJson === 'string') {
|
|
|
+ return JSON.parse(latestRecord.customerPortraitJson);
|
|
|
+ }
|
|
|
+ // 如果已经是对象,直接返回
|
|
|
+ return latestRecord.customerPortraitJson;
|
|
|
+ } catch (error) {
|
|
|
+ console.error('解析客户画像 JSON 失败:', error);
|
|
|
+ return {};
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return {};
|
|
|
+ },
|
|
|
+ // 客户关注点数据(从最新的沟通记录中获取)
|
|
|
+ customerFocusPoints() {
|
|
|
+ if (!this.communicationRecords || this.communicationRecords.length === 0) {
|
|
|
+ return ['暂无分析数据'];
|
|
|
+ }
|
|
|
+ const latestRecord = this.communicationRecords[0];
|
|
|
+ if (latestRecord && latestRecord.customerFocusJson) {
|
|
|
+ return this.normalizeFocusPoints(latestRecord.customerFocusJson);
|
|
|
+ }
|
|
|
+ return ['暂无分析数据'];
|
|
|
+ }
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ this.initFromParentOrRoute();
|
|
|
+ this.getDicts("trade_type").then((response) => {
|
|
|
+ this.tradeTypeOptions = response.data;
|
|
|
+ });
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ analyzeUserId: {
|
|
|
+ immediate: false,
|
|
|
+ handler() {
|
|
|
+ // 抽屉重复打开/切换客户时刷新
|
|
|
+ this.initFromParentOrRoute();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ analyzeExternalUserId() {
|
|
|
+ this.initFromParentOrRoute();
|
|
|
+ },
|
|
|
+ analyzeCorpId() {
|
|
|
+ this.initFromParentOrRoute();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ normalizeFocusPoints(value) {
|
|
|
+ if (value === null || value === undefined) return [];
|
|
|
+ if (Array.isArray(value)) {
|
|
|
+ return value.map(v => String(v)).filter(Boolean);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 字符串:可能是 JSON 数组字符串,也可能是普通字符串
|
|
|
+ if (typeof value === 'string') {
|
|
|
+ const raw = value.trim();
|
|
|
+ if (!raw) return [];
|
|
|
+
|
|
|
+ // JSON 数组 / JSON 字符串尝试解析
|
|
|
+ if (
|
|
|
+ (raw.startsWith('[') && raw.endsWith(']')) ||
|
|
|
+ (raw.startsWith('"') && raw.endsWith('"')) ||
|
|
|
+ (raw.startsWith("'") && raw.endsWith("'"))
|
|
|
+ ) {
|
|
|
+ try {
|
|
|
+ const parsed = JSON.parse(raw);
|
|
|
+ if (Array.isArray(parsed)) {
|
|
|
+ return parsed.map(v => String(v)).map(s => s.trim()).filter(Boolean);
|
|
|
+ }
|
|
|
+ if (typeof parsed === 'string') {
|
|
|
+ return this.normalizeFocusPoints(parsed);
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ // ignore,走后面的兜底清洗
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 兜底:去掉中括号/引号后按分隔符拆分
|
|
|
+ let cleaned = raw;
|
|
|
+ if (cleaned.startsWith('[') && cleaned.endsWith(']')) {
|
|
|
+ cleaned = cleaned.slice(1, -1);
|
|
|
+ }
|
|
|
+ cleaned = cleaned.replace(/["']/g, '');
|
|
|
+
|
|
|
+ const parts = cleaned
|
|
|
+ .split(/[,,、;;\n]/g)
|
|
|
+ .map(s => s.trim())
|
|
|
+ .filter(Boolean);
|
|
|
+
|
|
|
+ return parts.length ? parts : [cleaned.trim()].filter(Boolean);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 其它类型兜底
|
|
|
+ return [String(value)].filter(Boolean);
|
|
|
+ },
|
|
|
+ initFromParentOrRoute() {
|
|
|
+ // 优先用父组件传参(抽屉模式)
|
|
|
+ if (
|
|
|
+ (this.analyzeUserId !== null && this.analyzeUserId !== undefined && this.analyzeUserId !== '') ||
|
|
|
+ (this.analyzeExternalUserId !== null && this.analyzeExternalUserId !== undefined && this.analyzeExternalUserId !== '')
|
|
|
+ ) {
|
|
|
+ this.userId = this.analyzeUserId;
|
|
|
+ this.externalUserId = this.analyzeExternalUserId || (this.customerRow && (this.customerRow.externalUserId || this.customerRow.id));
|
|
|
+ this.corpId = this.analyzeCorpId;
|
|
|
+ this.customerData = this.customerRow || null;
|
|
|
+ } else {
|
|
|
+ // 路由模式兜底
|
|
|
+ this.userId = this.$route.query.userId || this.$route.query.qwUserId || this.$route.params.userId || this.$route.params.qwUserId;
|
|
|
+ this.externalUserId = this.$route.query.externalUserId || this.$route.query.id || this.$route.params.externalUserId || this.$route.params.id;
|
|
|
+ this.corpId = this.$route.query.corpId || this.$route.params.corpId;
|
|
|
+ if (this.$route.query.customerData) {
|
|
|
+ try {
|
|
|
+ this.customerData = JSON.parse(this.$route.query.customerData);
|
|
|
+ } catch (error) {
|
|
|
+ console.error('解析客户数据失败:', error);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 重置分页(切换客户时)
|
|
|
+ this.communicationRecordsPageNum = 1;
|
|
|
+ // 获取客户标签
|
|
|
+ this.loadCustomerTags();
|
|
|
+ // 加载客户分析信息
|
|
|
+ this.getCustomerInfoList();
|
|
|
+ },
|
|
|
+ loadCustomerTags() {
|
|
|
+ const params = {
|
|
|
+ externalUserId: this.externalUserId,
|
|
|
+ corpId: this.corpId,
|
|
|
+ qwUserId: this.userId,
|
|
|
+ };
|
|
|
+ return listByCustomerId(params).then((response) => {
|
|
|
+ if (response.code === 200) {
|
|
|
+ this.allAiTags = response.data || [];
|
|
|
+ // 强制 Vue 更新视图
|
|
|
+ this.$forceUpdate();
|
|
|
+ } else {
|
|
|
+ console.error('获取 AI 标签失败:', response);
|
|
|
+ }
|
|
|
+ }).catch(error => {
|
|
|
+ console.error('获取 AI 标签异常:', error);
|
|
|
+ });
|
|
|
+ },
|
|
|
+ handleAnalyzeTag() {
|
|
|
+ this.analyzeTagDialogVisible = true;
|
|
|
+ },
|
|
|
+ confirmAnalyzeTag() {
|
|
|
+ if (!this.selectedTradeType) {
|
|
|
+ this.$message.warning('请选择行业类型');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (!this.externalUserId || !this.corpId || !this.userId) {
|
|
|
+ this.$message.warning('客户参数不完整,无法分析标签');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const data = {
|
|
|
+ externalUserId: this.externalUserId,
|
|
|
+ corpId: this.corpId,
|
|
|
+ qwUserId: this.userId,
|
|
|
+ tradeType: this.selectedTradeType
|
|
|
+ };
|
|
|
+ this.analyzeTagSubmitting = true;
|
|
|
+ analyzeAiTagByTrade(data).then((res) => {
|
|
|
+ if (res && res.code === 200) {
|
|
|
+ this.$message.success(res.msg || 'AI分析标签成功');
|
|
|
+ this.analyzeTagDialogVisible = false;
|
|
|
+ this.loadCustomerTags();
|
|
|
+ } else {
|
|
|
+ this.$message.error((res && res.msg) || 'AI分析标签失败');
|
|
|
+ }
|
|
|
+ }).catch(() => {
|
|
|
+ this.$message.error('AI分析标签失败');
|
|
|
+ }).finally(() => {
|
|
|
+ this.analyzeTagSubmitting = false;
|
|
|
+ });
|
|
|
+ },
|
|
|
+ getCustomerInfoList() {
|
|
|
+ const params = {
|
|
|
+ pageNum: this.communicationRecordsPageNum,
|
|
|
+ pageSize: this.communicationRecordsPageSize,
|
|
|
+ qwUserId: this.userId,
|
|
|
+ externalUserId: this.externalUserId,
|
|
|
+ corpId: this.corpId
|
|
|
+ };
|
|
|
+ return listAnalyze(params).then((response) => {
|
|
|
+ if (response.code === 200) {
|
|
|
+ this.communicationRecords = response.rows || [];
|
|
|
+ this.communicationRecordsTotal = response.total || 0;
|
|
|
+ } else {
|
|
|
+ console.error('获取客户信息失败:', response);
|
|
|
+ }
|
|
|
+ }).catch(error => {
|
|
|
+ console.error('获取客户信息异常:', error);
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 加载更多标签 - 显示全部
|
|
|
+ loadMoreTags() {
|
|
|
+ this.isExpanded = true;
|
|
|
+ },
|
|
|
+ // 收起标签 - 只显示前 3 条
|
|
|
+ collapseTags() {
|
|
|
+ this.isExpanded = false;
|
|
|
+ },
|
|
|
+ // 查看聊天内容
|
|
|
+ viewChat(record) {
|
|
|
+ this.currentChatRecord = record;
|
|
|
+ this.chatDialogVisible = true;
|
|
|
+ },
|
|
|
+ // 关闭聊天弹窗
|
|
|
+ closeChatDialog() {
|
|
|
+ this.chatDialogVisible = false;
|
|
|
+ this.currentChatRecord = null;
|
|
|
+ },
|
|
|
+ // 解析聊天消息数组
|
|
|
+ parseChatMessages(content) {
|
|
|
+ if (!content) {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+ // 如果 content 是字符串,尝试解析为 JSON 数组
|
|
|
+ if (typeof content === 'string') {
|
|
|
+ try {
|
|
|
+ const parsed = JSON.parse(content);
|
|
|
+ // 如果是数组,直接返回
|
|
|
+ if (Array.isArray(parsed)) {
|
|
|
+ return parsed.map(item => ({
|
|
|
+ content: item.ai || item.user,
|
|
|
+ type: item.ai ? 'ai' : 'user'
|
|
|
+ }));
|
|
|
+ }
|
|
|
+ // 如果是对象,转换为数组
|
|
|
+ return [{content: parsed.content, type: parsed.type || 'ai'}];
|
|
|
+ } catch (e) {
|
|
|
+ // 解析失败,返回空数组
|
|
|
+ console.error('解析聊天记录失败:', e);
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 如果已经是数组,直接返回
|
|
|
+ if (Array.isArray(content)) {
|
|
|
+ return content;
|
|
|
+ }
|
|
|
+ // 如果是对象,转换为数组
|
|
|
+ return [content];
|
|
|
+ },
|
|
|
+ // 处理头像加载失败
|
|
|
+ handleAvatarError(event, type) {
|
|
|
+ const img = event.target;
|
|
|
+ if (type === 'ai') {
|
|
|
+ // AI 头像加载失败时,使用渐变色背景 + 机器人图标
|
|
|
+ img.style.display = 'none';
|
|
|
+ img.parentElement.innerHTML = '<i class="fas fa-robot" style="font-size: 24px; color: white;"></i>';
|
|
|
+ } else {
|
|
|
+ // 客户头像加载失败时,使用渐变色背景 + 用户图标
|
|
|
+ img.style.display = 'none';
|
|
|
+ img.parentElement.innerHTML = '<i class="fas fa-user" style="font-size: 24px; color: white;"></i>';
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 分页改变事件
|
|
|
+ handleCommunicationRecordsPageChange(pageNum) {
|
|
|
+ this.communicationRecordsPageNum = pageNum;
|
|
|
+ this.getCustomerInfoList();
|
|
|
+ },
|
|
|
+ // 每页条数改变事件
|
|
|
+ handleCommunicationRecordsSizeChange(pageSize) {
|
|
|
+ this.communicationRecordsPageSize = pageSize;
|
|
|
+ this.communicationRecordsPageNum = 1; // 重置为第一页
|
|
|
+ this.getCustomerInfoList();
|
|
|
+ },
|
|
|
+ // 获取沟通摘要
|
|
|
+ getCommunicationAbstract() {
|
|
|
+ if (!this.communicationRecords || this.communicationRecords.length === 0) {
|
|
|
+ return '暂无沟通记录';
|
|
|
+ }
|
|
|
+ const latestRecord = this.communicationRecords[0];
|
|
|
+ return latestRecord.communicationAbstract || '暂无沟通摘要';
|
|
|
+ },
|
|
|
+ // 获取 AI 沟通总结
|
|
|
+ getCommunicationSummary() {
|
|
|
+ if (!this.communicationRecords || this.communicationRecords.length === 0) {
|
|
|
+ return '暂无沟通记录';
|
|
|
+ }
|
|
|
+ const latestRecord = this.communicationRecords[0];
|
|
|
+ return latestRecord.communicationSummary || '暂无 AI 沟通总结';
|
|
|
+ },
|
|
|
+ // 获取最后更新时间
|
|
|
+ getUpdateTime() {
|
|
|
+ if (!this.communicationRecords || this.communicationRecords.length === 0) {
|
|
|
+ return '-';
|
|
|
+ }
|
|
|
+ const latestRecord = this.communicationRecords[0];
|
|
|
+ return latestRecord.createTime || '-';
|
|
|
+ },
|
|
|
+ // 获取流失风险等级数值
|
|
|
+ getAttritionLevel() {
|
|
|
+ if (!this.communicationRecords || this.communicationRecords.length === 0) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ const latestRecord = this.communicationRecords[0];
|
|
|
+ return parseInt(latestRecord.attritionLevel) || 0;
|
|
|
+ },
|
|
|
+ // 获取流失风险等级标签
|
|
|
+ getRiskLevelLabel() {
|
|
|
+ const level = this.getAttritionLevel();
|
|
|
+ const labels = ['未知', '无风险', '低风险', '中风险', '高风险'];
|
|
|
+ return labels[level] || '未知';
|
|
|
+ },
|
|
|
+ // 获取流失风险等级徽章样式类
|
|
|
+ getRiskLevelBadgeClass() {
|
|
|
+ const level = this.getAttritionLevel();
|
|
|
+ const badgeClasses = [
|
|
|
+ 'badge-unknown',
|
|
|
+ 'badge-none',
|
|
|
+ 'badge-low',
|
|
|
+ 'badge-medium',
|
|
|
+ 'badge-high'
|
|
|
+ ];
|
|
|
+ return badgeClasses[level] || 'badge-unknown';
|
|
|
+ },
|
|
|
+ // 获取客户意向度
|
|
|
+ getIntentionDegree() {
|
|
|
+ if (!this.communicationRecords || this.communicationRecords.length === 0) {
|
|
|
+ return '';
|
|
|
+ }
|
|
|
+ const latestRecord = this.communicationRecords[0];
|
|
|
+ return latestRecord.intentionDegree || '';
|
|
|
+ },
|
|
|
+ // 根据意向度等级获取颜色样式类
|
|
|
+ getIntentionColorClass(grade) {
|
|
|
+ if (!grade) return '';
|
|
|
+ const gradeUpper = grade.toUpperCase();
|
|
|
+ const colorMap = {
|
|
|
+ 'A': 'intention-grade-a',
|
|
|
+ 'B': 'intention-grade-b',
|
|
|
+ 'C': 'intention-grade-c',
|
|
|
+ 'D': 'intention-grade-d',
|
|
|
+ 'E': 'intention-grade-e',
|
|
|
+ 'F': 'intention-grade-f'
|
|
|
+ };
|
|
|
+ return colorMap[gradeUpper] || '';
|
|
|
+ },
|
|
|
+ // 获取单条记录的风险等级数值
|
|
|
+ getRecordAttritionLevel(record) {
|
|
|
+ if (!record) return 0;
|
|
|
+ return parseInt(record.attritionLevel) || 0;
|
|
|
+ },
|
|
|
+ // 获取单条记录的风险等级标签
|
|
|
+ getRecordRiskLevelLabel(record) {
|
|
|
+ const level = this.getRecordAttritionLevel(record);
|
|
|
+ const labels = ['未知', '无风险', '低风险', '中风险', '高风险'];
|
|
|
+ return labels[level] || '未知';
|
|
|
+ },
|
|
|
+ // 获取单条记录的风险等级样式类
|
|
|
+ getRecordRiskLevelClass(record) {
|
|
|
+ const level = this.getRecordAttritionLevel(record);
|
|
|
+ const classes = ['risk-unknown', 'risk-none', 'risk-low', 'risk-medium', 'risk-high'];
|
|
|
+ return classes[level] || 'risk-unknown';
|
|
|
+ },
|
|
|
+ // 获取单条记录的客户意向度
|
|
|
+ getIntentionDegreeFromRecord(record) {
|
|
|
+ if (!record) return 0;
|
|
|
+ return record.intentionDegree;
|
|
|
+ },
|
|
|
+ // 获取流失风险等级样式类
|
|
|
+ getRiskLevelClass() {
|
|
|
+ const level = this.getAttritionLevel();
|
|
|
+ const classes = ['risk-unknown', 'risk-none', 'risk-low', 'risk-medium', 'risk-high'];
|
|
|
+ return classes[level] || 'risk-unknown';
|
|
|
+ },
|
|
|
+ // 获取流失风险分析
|
|
|
+ getRiskLevelAnalysis() {
|
|
|
+ const level = this.getAttritionLevel();
|
|
|
+ if (!this.communicationRecords || this.communicationRecords.length === 0) {
|
|
|
+ return '暂无分析数据';
|
|
|
+ }
|
|
|
+ const latestRecord = this.communicationRecords[0];
|
|
|
+ return latestRecord.attritionLevelPrompt || "暂无分析数据";
|
|
|
+ },
|
|
|
+ // 获取流失风险提示
|
|
|
+ getRiskLevelTip() {
|
|
|
+ const level = this.getAttritionLevel();
|
|
|
+ const tips = [
|
|
|
+ '暂无分析',
|
|
|
+ '客户稳定,可以放心。',
|
|
|
+ '建议定期回访,了解客户最新需求。',
|
|
|
+ '建议安排专项跟进,深入了解客户痛点和需求。',
|
|
|
+ '建议立即联系客户,了解问题原因并提供解决方案。'
|
|
|
+ ];
|
|
|
+ return tips[level] || '';
|
|
|
+ },
|
|
|
+ }
|
|
|
+}</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+* {
|
|
|
+ box-sizing: border-box;
|
|
|
+}
|
|
|
+
|
|
|
+.left-column {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 12px;
|
|
|
+}
|
|
|
+
|
|
|
+.middle-column {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 12px;
|
|
|
+}
|
|
|
+
|
|
|
+.right-column {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 12px;
|
|
|
+}
|
|
|
+
|
|
|
+.customer-container {
|
|
|
+ max-width: 1600px;
|
|
|
+ margin: 0 auto;
|
|
|
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
|
+ background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
|
|
|
+ padding: 8px;
|
|
|
+ min-height: calc(100vh - 50px);
|
|
|
+}
|
|
|
+
|
|
|
+@keyframes pulse {
|
|
|
+ 0%, 100% {
|
|
|
+ transform: scale(1);
|
|
|
+ }
|
|
|
+ 50% {
|
|
|
+ transform: scale(1.1);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.main-grid-three-columns {
|
|
|
+ display: grid;
|
|
|
+ grid-template-columns: 380px 1fr 340px;
|
|
|
+ gap: 12px;
|
|
|
+ animation: fadeIn 0.6s ease-in-out;
|
|
|
+ align-items: stretch;
|
|
|
+}
|
|
|
+
|
|
|
+@keyframes fadeIn {
|
|
|
+ from {
|
|
|
+ opacity: 0;
|
|
|
+ transform: translateY(20px);
|
|
|
+ }
|
|
|
+ to {
|
|
|
+ opacity: 1;
|
|
|
+ transform: translateY(0);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+@media (max-width: 1400px) {
|
|
|
+ .main-grid-three-columns {
|
|
|
+ grid-template-columns: 360px 1fr 320px;
|
|
|
+ gap: 24px;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+@media (max-width: 1200px) {
|
|
|
+ .main-grid-three-columns {
|
|
|
+ grid-template-columns: 1fr;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.card {
|
|
|
+ background: white;
|
|
|
+ border-radius: 12px;
|
|
|
+ padding: 12px;
|
|
|
+ margin-bottom: 12px;
|
|
|
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.06);
|
|
|
+ transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
|
|
+ border: 1px solid rgba(226, 232, 240, 0.5);
|
|
|
+ position: relative;
|
|
|
+ overflow: hidden;
|
|
|
+}
|
|
|
+
|
|
|
+.card::before {
|
|
|
+ content: '';
|
|
|
+ position: absolute;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ height: 3px;
|
|
|
+ background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
|
|
|
+ transform: scaleX(0);
|
|
|
+ transition: transform 0.4s ease;
|
|
|
+}
|
|
|
+
|
|
|
+.card:hover::before {
|
|
|
+ transform: scaleX(1);
|
|
|
+}
|
|
|
+
|
|
|
+.card:hover {
|
|
|
+ box-shadow: 0 12px 48px rgba(0, 0, 0, 0.15);
|
|
|
+ transform: translateY(-4px);
|
|
|
+ border-color: rgba(102, 126, 234, 0.3);
|
|
|
+}
|
|
|
+
|
|
|
+/* 高亮卡片(AI 总结) */
|
|
|
+.card-highlight {
|
|
|
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
|
+ color: white;
|
|
|
+ border: none;
|
|
|
+ box-shadow: 0 8px 32px rgba(102, 126, 234, 0.4);
|
|
|
+ position: relative;
|
|
|
+ overflow: hidden;
|
|
|
+}
|
|
|
+
|
|
|
+.card-highlight::after {
|
|
|
+ content: '';
|
|
|
+ position: absolute;
|
|
|
+ top: -50%;
|
|
|
+ right: -50%;
|
|
|
+ width: 200%;
|
|
|
+ height: 200%;
|
|
|
+ background: radial-gradient(circle, rgba(255, 255, 255, 0.1) 0%, transparent 70%);
|
|
|
+ animation: shimmer 3s infinite;
|
|
|
+}
|
|
|
+
|
|
|
+@keyframes shimmer {
|
|
|
+ 0%, 100% {
|
|
|
+ transform: translate(0, 0);
|
|
|
+ }
|
|
|
+ 50% {
|
|
|
+ transform: translate(-30%, -30%);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.card-highlight .card-header h3 {
|
|
|
+ color: white;
|
|
|
+}
|
|
|
+
|
|
|
+.card-highlight .summary-text {
|
|
|
+ color: white;
|
|
|
+ font-size: 17px;
|
|
|
+ line-height: 1.6;
|
|
|
+ max-height: 120px;
|
|
|
+ overflow-y: auto;
|
|
|
+ overflow-x: hidden;
|
|
|
+ padding-right: 4px;
|
|
|
+}
|
|
|
+
|
|
|
+.card-highlight .summary-text::-webkit-scrollbar {
|
|
|
+ width: 6px;
|
|
|
+}
|
|
|
+
|
|
|
+.card-highlight .summary-text::-webkit-scrollbar-track {
|
|
|
+ background: rgba(255, 255, 255, 0.2);
|
|
|
+ border-radius: 3px;
|
|
|
+}
|
|
|
+
|
|
|
+.card-highlight .summary-text::-webkit-scrollbar-thumb {
|
|
|
+ background: rgba(255, 255, 255, 0.4);
|
|
|
+ border-radius: 3px;
|
|
|
+}
|
|
|
+
|
|
|
+.card-highlight .summary-text::-webkit-scrollbar-thumb:hover {
|
|
|
+ background: rgba(255, 255, 255, 0.6);
|
|
|
+}
|
|
|
+
|
|
|
+.card-highlight .summary-meta span {
|
|
|
+ color: rgba(255, 255, 255, 0.9);
|
|
|
+}
|
|
|
+
|
|
|
+/* 表格卡片 */
|
|
|
+.card-table {
|
|
|
+ background: white;
|
|
|
+}
|
|
|
+
|
|
|
+/* 风险卡片 */
|
|
|
+.risk-card {
|
|
|
+ border-left: 4px solid #10b981;
|
|
|
+ background: linear-gradient(135deg, #f0fdf4 0%, #dcfce7 100%);
|
|
|
+ transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
|
|
+}
|
|
|
+
|
|
|
+.risk-card.risk-unknown {
|
|
|
+ border-left-color: #6b7280;
|
|
|
+ background: linear-gradient(135deg, #f9fafb 0%, #f3f4f6 100%);
|
|
|
+}
|
|
|
+
|
|
|
+.risk-card.risk-unknown::before {
|
|
|
+ background: linear-gradient(90deg, #6b7280 0%, #4b5563 100%);
|
|
|
+}
|
|
|
+
|
|
|
+.risk-card::before {
|
|
|
+ background: linear-gradient(90deg, #10b981 0%, #34d399 100%);
|
|
|
+}
|
|
|
+
|
|
|
+.risk-unknown .risk-badge {
|
|
|
+ background: linear-gradient(135deg, #6b7280 0%, #4b5563 100%);
|
|
|
+ box-shadow: 0 2px 8px rgba(107, 114, 128, 0.3);
|
|
|
+}
|
|
|
+
|
|
|
+.risk-none .risk-badge {
|
|
|
+ background: linear-gradient(135deg, #10b981 0%, #34d399 100%);
|
|
|
+ box-shadow: 0 2px 8px rgba(16, 185, 129, 0.3);
|
|
|
+}
|
|
|
+
|
|
|
+.risk-low .risk-badge {
|
|
|
+ background: linear-gradient(135deg, #3b82f6 0%, #60a5fa 100%);
|
|
|
+ box-shadow: 0 2px 8px rgba(59, 130, 246, 0.3);
|
|
|
+}
|
|
|
+
|
|
|
+.risk-medium .risk-badge {
|
|
|
+ background: linear-gradient(135deg, #f59e0b 0%, #fbbf24 100%);
|
|
|
+ box-shadow: 0 2px 8px rgba(245, 158, 11, 0.3);
|
|
|
+}
|
|
|
+
|
|
|
+.risk-high .risk-badge {
|
|
|
+ background: linear-gradient(135deg, #ef4444 0%, #f87171 100%);
|
|
|
+ box-shadow: 0 2px 8px rgba(239, 68, 68, 0.3);
|
|
|
+}
|
|
|
+
|
|
|
+.risk-card:hover {
|
|
|
+ transform: translateY(-2px);
|
|
|
+ box-shadow: 0 12px 48px rgba(0, 0, 0, 0.1);
|
|
|
+}
|
|
|
+
|
|
|
+/* 风险等级标签 */
|
|
|
+.risk-badge {
|
|
|
+ display: inline-flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 6px;
|
|
|
+ padding: 6px 14px;
|
|
|
+ border-radius: 8px;
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: 700;
|
|
|
+ color: white;
|
|
|
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
|
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
|
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
|
|
|
+}
|
|
|
+
|
|
|
+.risk-badge::before {
|
|
|
+ content: '';
|
|
|
+ width: 6px;
|
|
|
+ height: 6px;
|
|
|
+ background: white;
|
|
|
+ border-radius: 50%;
|
|
|
+ animation: pulse 2s infinite;
|
|
|
+}
|
|
|
+
|
|
|
+@keyframes pulse {
|
|
|
+ 0%, 100% {
|
|
|
+ opacity: 1;
|
|
|
+ transform: scale(1);
|
|
|
+ }
|
|
|
+ 50% {
|
|
|
+ opacity: 0.5;
|
|
|
+ transform: scale(1.2);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.risk-card:hover .risk-badge {
|
|
|
+ transform: scale(1.05);
|
|
|
+}
|
|
|
+
|
|
|
+/* 风险分析内容 */
|
|
|
+.risk-analysis {
|
|
|
+ margin-top: 10px;
|
|
|
+ padding: 10px;
|
|
|
+ background: rgba(255, 255, 255, 0.7);
|
|
|
+ border-radius: 10px;
|
|
|
+ backdrop-filter: blur(10px);
|
|
|
+ max-height: 180px;
|
|
|
+ overflow-y: auto;
|
|
|
+ overflow-x: hidden;
|
|
|
+ padding-right: 4px;
|
|
|
+}
|
|
|
+
|
|
|
+.risk-analysis::-webkit-scrollbar {
|
|
|
+ width: 6px;
|
|
|
+}
|
|
|
+
|
|
|
+.risk-analysis::-webkit-scrollbar-track {
|
|
|
+ background: rgba(255, 255, 255, 0.5);
|
|
|
+ border-radius: 3px;
|
|
|
+}
|
|
|
+
|
|
|
+.risk-analysis::-webkit-scrollbar-thumb {
|
|
|
+ background: linear-gradient(180deg, #cbd5e1 0%, #94a3b8 100%);
|
|
|
+ border-radius: 3px;
|
|
|
+}
|
|
|
+
|
|
|
+.risk-analysis::-webkit-scrollbar-thumb:hover {
|
|
|
+ background: linear-gradient(180deg, #94a3b8 0%, #64748b 100%);
|
|
|
+}
|
|
|
+
|
|
|
+.risk-text {
|
|
|
+ font-size: 16px;
|
|
|
+ line-height: 1.7;
|
|
|
+ color: #475569;
|
|
|
+ margin: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.risk-tip {
|
|
|
+ margin-top: 8px;
|
|
|
+ padding: 8px;
|
|
|
+ background: linear-gradient(135deg, rgba(255, 255, 255, 0.9) 0%, rgba(248, 250, 252, 0.9) 100%);
|
|
|
+ border-left: 3px solid #f59e0b;
|
|
|
+ border-radius: 6px;
|
|
|
+ font-size: 15px;
|
|
|
+ color: #92400e;
|
|
|
+ display: flex;
|
|
|
+ align-items: flex-start;
|
|
|
+ gap: 6px;
|
|
|
+}
|
|
|
+
|
|
|
+.risk-tip i {
|
|
|
+ font-size: 12px;
|
|
|
+ margin-top: 1px;
|
|
|
+ color: #f59e0b;
|
|
|
+}
|
|
|
+
|
|
|
+/* 关注点卡片 */
|
|
|
+.card-focus {
|
|
|
+ background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%);
|
|
|
+ border: 2px solid #bae6fd;
|
|
|
+ box-shadow: 0 4px 16px rgba(186, 230, 253, 0.3);
|
|
|
+}
|
|
|
+
|
|
|
+.card-header {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ border-bottom: 1px solid #eef2ff;
|
|
|
+ padding-bottom: 6px;
|
|
|
+ margin-bottom: 10px;
|
|
|
+ flex-wrap: wrap;
|
|
|
+}
|
|
|
+
|
|
|
+.card-header h3 {
|
|
|
+ font-size: 19px;
|
|
|
+ font-weight: 700;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 8px;
|
|
|
+ color: #0f172a;
|
|
|
+ letter-spacing: -0.02em;
|
|
|
+}
|
|
|
+
|
|
|
+.records-table-wrapper {
|
|
|
+ overflow-x: auto;
|
|
|
+}
|
|
|
+
|
|
|
+/* 分页容器样式 */
|
|
|
+.pagination-container {
|
|
|
+ padding: 16px 0 12px;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ background: white;
|
|
|
+ border-top: 1px solid #f1f5f9;
|
|
|
+ margin-top: 12px;
|
|
|
+}
|
|
|
+
|
|
|
+/* Element UI 分页样式覆盖 */
|
|
|
+
|
|
|
+.pagination-container .el-pagination li {
|
|
|
+ min-width: 32px;
|
|
|
+ height: 32px;
|
|
|
+ line-height: 32px;
|
|
|
+ border-radius: 6px;
|
|
|
+ transition: all 0.3s ease;
|
|
|
+}
|
|
|
+
|
|
|
+.pagination-container .el-pagination li:hover {
|
|
|
+ background: linear-gradient(135deg, rgba(102, 126, 234, 0.1) 0%, rgba(118, 75, 162, 0.1) 100%);
|
|
|
+ border-color: #667eea;
|
|
|
+}
|
|
|
+
|
|
|
+.records-table {
|
|
|
+ width: 100%;
|
|
|
+ border-collapse: collapse;
|
|
|
+ font-size: 15px;
|
|
|
+}
|
|
|
+
|
|
|
+.records-table thead {
|
|
|
+ background: transparent;
|
|
|
+ color: #475569;
|
|
|
+}
|
|
|
+
|
|
|
+.records-table th {
|
|
|
+ padding: 12px 16px;
|
|
|
+ text-align: center !important;
|
|
|
+ font-weight: 600;
|
|
|
+ font-size: 14px;
|
|
|
+ border-bottom: 2px solid #e2e8f0;
|
|
|
+ color: #64748b;
|
|
|
+}
|
|
|
+
|
|
|
+.records-table th i {
|
|
|
+ margin-right: 6px;
|
|
|
+ opacity: 0.8;
|
|
|
+}
|
|
|
+
|
|
|
+.records-table tbody tr {
|
|
|
+ border-bottom: 1px solid #f1f5f9;
|
|
|
+ transition: all 0.2s ease;
|
|
|
+}
|
|
|
+
|
|
|
+.records-table tbody tr:hover {
|
|
|
+ background-color: #f8fafc;
|
|
|
+ transform: none;
|
|
|
+ box-shadow: none;
|
|
|
+}
|
|
|
+
|
|
|
+.records-table td {
|
|
|
+ padding: 12px 16px;
|
|
|
+ vertical-align: middle;
|
|
|
+}
|
|
|
+
|
|
|
+.record-cell {
|
|
|
+ font-size: 15px;
|
|
|
+ color: #334155;
|
|
|
+ text-align: center !important;
|
|
|
+}
|
|
|
+
|
|
|
+/* 风险等级标签 */
|
|
|
+.risk-level-tag {
|
|
|
+ display: inline-block;
|
|
|
+ padding: 4px 12px;
|
|
|
+ border-radius: 6px;
|
|
|
+ font-size: 13px;
|
|
|
+ font-weight: 500;
|
|
|
+ border: 1px solid;
|
|
|
+}
|
|
|
+
|
|
|
+/* 客户意向度 */
|
|
|
+.intention-degree {
|
|
|
+ display: inline-block;
|
|
|
+ padding: 4px 12px;
|
|
|
+ border-radius: 6px;
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #6366f1;
|
|
|
+ background: rgba(99, 102, 241, 0.08);
|
|
|
+ border: 1px solid rgba(99, 102, 241, 0.2);
|
|
|
+}
|
|
|
+
|
|
|
+.btn-view-chat {
|
|
|
+ background: transparent;
|
|
|
+ color: #667eea;
|
|
|
+ border: 1px solid #667eea;
|
|
|
+ padding: 6px 12px;
|
|
|
+ border-radius: 6px;
|
|
|
+ font-size: 14px;
|
|
|
+ cursor: pointer;
|
|
|
+ display: inline-flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 4px;
|
|
|
+ transition: all 0.2s ease;
|
|
|
+}
|
|
|
+
|
|
|
+.btn-view-chat:hover {
|
|
|
+ background: #f0f4ff;
|
|
|
+}
|
|
|
+
|
|
|
+.empty-tip {
|
|
|
+ color: #94a3b8;
|
|
|
+ font-size: 16px;
|
|
|
+ text-align: center;
|
|
|
+ padding: 40px 20px;
|
|
|
+ background: transparent;
|
|
|
+ border: none;
|
|
|
+}
|
|
|
+
|
|
|
+/* 沟通摘要样式 */
|
|
|
+.summary-text.compact {
|
|
|
+ max-height: 100px;
|
|
|
+ overflow-y: auto;
|
|
|
+ overflow-x: hidden;
|
|
|
+ line-height: 1.6;
|
|
|
+ font-size: 16px;
|
|
|
+ color: #475569;
|
|
|
+ padding-right: 4px;
|
|
|
+}
|
|
|
+
|
|
|
+.summary-text.compact::-webkit-scrollbar {
|
|
|
+ width: 6px;
|
|
|
+}
|
|
|
+
|
|
|
+.summary-text.compact::-webkit-scrollbar-track {
|
|
|
+ background: #f1f5f9;
|
|
|
+ border-radius: 3px;
|
|
|
+}
|
|
|
+
|
|
|
+.summary-text.compact::-webkit-scrollbar-thumb {
|
|
|
+ background: linear-gradient(180deg, #cbd5e1 0%, #94a3b8 100%);
|
|
|
+ border-radius: 3px;
|
|
|
+}
|
|
|
+
|
|
|
+.summary-text.compact::-webkit-scrollbar-thumb:hover {
|
|
|
+ background: linear-gradient(180deg, #94a3b8 0%, #64748b 100%);
|
|
|
+}
|
|
|
+
|
|
|
+/* AI 标签美化样式 */
|
|
|
+.tags-container {
|
|
|
+ padding: 0;
|
|
|
+ min-height: calc(16px * 5 + 6px * 4 + 12px * 2);
|
|
|
+ overflow-y: auto;
|
|
|
+ overflow-x: hidden;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+}
|
|
|
+
|
|
|
+.tags-container::-webkit-scrollbar {
|
|
|
+ width: 6px;
|
|
|
+}
|
|
|
+
|
|
|
+.tags-container::-webkit-scrollbar-track {
|
|
|
+ background: #f1f5f9;
|
|
|
+ border-radius: 3px;
|
|
|
+}
|
|
|
+
|
|
|
+.tags-container::-webkit-scrollbar-thumb {
|
|
|
+ background: linear-gradient(180deg, #cbd5e1 0%, #94a3b8 100%);
|
|
|
+ border-radius: 3px;
|
|
|
+}
|
|
|
+
|
|
|
+.tags-container::-webkit-scrollbar-thumb:hover {
|
|
|
+ background: linear-gradient(180deg, #94a3b8 0%, #64748b 100%);
|
|
|
+}
|
|
|
+
|
|
|
+/* 标签列表 - 每行一个 */
|
|
|
+.tags-list {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 6px;
|
|
|
+ margin-bottom: 6px;
|
|
|
+}
|
|
|
+
|
|
|
+.tag-item {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 6px;
|
|
|
+ padding: 6px 10px;
|
|
|
+ background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
|
|
|
+ border: 1px solid #e2e8f0;
|
|
|
+ border-radius: 6px;
|
|
|
+ font-size: 15px;
|
|
|
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
|
+ cursor: default;
|
|
|
+ position: relative;
|
|
|
+ overflow: hidden;
|
|
|
+}
|
|
|
+
|
|
|
+.tag-item::before {
|
|
|
+ content: '';
|
|
|
+ position: absolute;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ width: 4px;
|
|
|
+ height: 100%;
|
|
|
+ background: linear-gradient(180deg, #94a3b8 0%, #64748b 100%);
|
|
|
+ transition: width 0.3s ease;
|
|
|
+}
|
|
|
+
|
|
|
+.tag-item:hover {
|
|
|
+ background: linear-gradient(135deg, #f1f5f9 0%, #e2e8f0 100%);
|
|
|
+ border-color: #cbd5e1;
|
|
|
+ transform: translateX(6px);
|
|
|
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
|
|
+}
|
|
|
+
|
|
|
+.tag-item:hover::before {
|
|
|
+ width: 5px;
|
|
|
+ background: linear-gradient(180deg, #3b82f6 0%, #2563eb 100%);
|
|
|
+}
|
|
|
+
|
|
|
+.tag-highlight {
|
|
|
+ background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);
|
|
|
+ border-color: #bfdbfe;
|
|
|
+}
|
|
|
+
|
|
|
+.tag-highlight::before {
|
|
|
+ background: linear-gradient(180deg, #3b82f6 0%, #2563eb 100%);
|
|
|
+}
|
|
|
+
|
|
|
+.tag-key {
|
|
|
+ font-weight: 600;
|
|
|
+ color: #475569;
|
|
|
+ white-space: nowrap;
|
|
|
+ flex-shrink: 0;
|
|
|
+ font-size: 15px;
|
|
|
+}
|
|
|
+
|
|
|
+.tag-separator {
|
|
|
+ color: #94a3b8;
|
|
|
+ font-weight: 300;
|
|
|
+ flex-shrink: 0;
|
|
|
+ font-size: 15px;
|
|
|
+}
|
|
|
+
|
|
|
+.tag-value {
|
|
|
+ color: #1e293b;
|
|
|
+ font-weight: 500;
|
|
|
+ word-break: break-word;
|
|
|
+ flex: 1;
|
|
|
+ min-width: 0;
|
|
|
+ font-size: 15px;
|
|
|
+}
|
|
|
+
|
|
|
+.empty-tags {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ padding: 40px 20px;
|
|
|
+ color: #94a3b8;
|
|
|
+ font-size: 17px;
|
|
|
+ background: linear-gradient(135deg, rgba(248, 250, 252, 0.5) 0%, rgba(241, 245, 249, 0.5) 100%);
|
|
|
+ border-radius: 12px;
|
|
|
+ border: 2px dashed #e2e8f0;
|
|
|
+}
|
|
|
+
|
|
|
+.empty-tags i {
|
|
|
+ font-size: 32px;
|
|
|
+ margin-bottom: 12px;
|
|
|
+ opacity: 0.5;
|
|
|
+}
|
|
|
+
|
|
|
+.tags-actions {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ padding: 16px 0;
|
|
|
+ border-top: 1px solid #f1f5f9;
|
|
|
+ margin-top: auto;
|
|
|
+ background: white;
|
|
|
+ position: sticky;
|
|
|
+ bottom: 0;
|
|
|
+ z-index: 10;
|
|
|
+}
|
|
|
+
|
|
|
+.btn-expand-tags,
|
|
|
+.btn-collapse-tags {
|
|
|
+ background: transparent;
|
|
|
+ color: #667eea;
|
|
|
+ border: 1px solid #667eea;
|
|
|
+ padding: 8px 16px;
|
|
|
+ border-radius: 6px;
|
|
|
+ font-size: 16px;
|
|
|
+ cursor: pointer;
|
|
|
+ display: inline-flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 6px;
|
|
|
+ transition: all 0.2s ease;
|
|
|
+}
|
|
|
+
|
|
|
+.btn-expand-tags:hover,
|
|
|
+.btn-collapse-tags:hover {
|
|
|
+ background: rgba(102, 126, 234, 0.05);
|
|
|
+ border-color: #5a67d8;
|
|
|
+ color: #5a67d8;
|
|
|
+}
|
|
|
+
|
|
|
+.btn-expand-tags:active,
|
|
|
+.btn-collapse-tags:active {
|
|
|
+ transform: scale(0.98);
|
|
|
+}
|
|
|
+
|
|
|
+/* 微信风格聊天弹窗 */
|
|
|
+.chat-dialog-overlay {
|
|
|
+ position: fixed;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ bottom: 0;
|
|
|
+ background: rgba(0, 0, 0, 0.5);
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ z-index: 9999;
|
|
|
+ backdrop-filter: blur(4px);
|
|
|
+}
|
|
|
+
|
|
|
+.chat-dialog {
|
|
|
+ background: white;
|
|
|
+ border-radius: 16px;
|
|
|
+ width: 90%;
|
|
|
+ max-width: 800px;
|
|
|
+ height: 600px;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
|
|
|
+ animation: slideIn 0.3s ease-out;
|
|
|
+ position: relative;
|
|
|
+}
|
|
|
+
|
|
|
+@keyframes slideIn {
|
|
|
+ from {
|
|
|
+ opacity: 0;
|
|
|
+ transform: translateY(-20px);
|
|
|
+ }
|
|
|
+ to {
|
|
|
+ opacity: 1;
|
|
|
+ transform: translateY(0);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.chat-dialog-header {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ padding: 16px 20px;
|
|
|
+ border-bottom: 1px solid #eef2ff;
|
|
|
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
|
+ border-radius: 16px 16px 0 0;
|
|
|
+ color: white;
|
|
|
+}
|
|
|
+
|
|
|
+.chat-title {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 10px;
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: 700;
|
|
|
+}
|
|
|
+
|
|
|
+.btn-close {
|
|
|
+ position: absolute;
|
|
|
+ top: 16px;
|
|
|
+ right: 16px;
|
|
|
+ background: white;
|
|
|
+ border: 2px solid #e2e8f0;
|
|
|
+ color: #1a202c;
|
|
|
+ width: 36px;
|
|
|
+ height: 36px;
|
|
|
+ border-radius: 50%;
|
|
|
+ cursor: pointer;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ transition: all 0.3s ease;
|
|
|
+ font-size: 24px;
|
|
|
+ font-weight: bold;
|
|
|
+ line-height: 1;
|
|
|
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
|
+ z-index: 10;
|
|
|
+}
|
|
|
+
|
|
|
+.btn-close:hover {
|
|
|
+ background: #ef4444;
|
|
|
+ border-color: #ef4444;
|
|
|
+ color: white;
|
|
|
+ transform: rotate(90deg) scale(1.1);
|
|
|
+ box-shadow: 0 4px 16px rgba(239, 68, 68, 0.4);
|
|
|
+}
|
|
|
+
|
|
|
+.chat-dialog-body {
|
|
|
+ flex: 1;
|
|
|
+ overflow-y: auto;
|
|
|
+ padding: 20px;
|
|
|
+ background: #f5f7fa;
|
|
|
+}
|
|
|
+
|
|
|
+.chat-messages {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 16px;
|
|
|
+}
|
|
|
+
|
|
|
+.message-item {
|
|
|
+ display: flex;
|
|
|
+ align-items: flex-start;
|
|
|
+ margin-bottom: 8px;
|
|
|
+}
|
|
|
+
|
|
|
+.message-left {
|
|
|
+ justify-content: flex-start;
|
|
|
+}
|
|
|
+
|
|
|
+.message-right {
|
|
|
+ justify-content: flex-end;
|
|
|
+}
|
|
|
+
|
|
|
+/* 客户消息强制布局:头像在右 */
|
|
|
+.message-item-customer {
|
|
|
+ display: flex !important;
|
|
|
+ flex-direction: row !important;
|
|
|
+ justify-content: flex-end !important;
|
|
|
+ gap: 10px !important;
|
|
|
+}
|
|
|
+
|
|
|
+.message-wrapper {
|
|
|
+ display: flex;
|
|
|
+ align-items: flex-start;
|
|
|
+ gap: 10px;
|
|
|
+ max-width: 75%;
|
|
|
+}
|
|
|
+
|
|
|
+.message-wrapper-left {
|
|
|
+ flex-direction: row;
|
|
|
+}
|
|
|
+
|
|
|
+.message-name {
|
|
|
+ font-size: 12px;
|
|
|
+ color: #94a3b8;
|
|
|
+ white-space: nowrap;
|
|
|
+ text-align: left;
|
|
|
+ margin-bottom: 4px;
|
|
|
+ line-height: 1.2;
|
|
|
+}
|
|
|
+
|
|
|
+.message-name-ai {
|
|
|
+ color: #667eea;
|
|
|
+ font-weight: 500;
|
|
|
+}
|
|
|
+
|
|
|
+.message-avatar {
|
|
|
+ width: 32px;
|
|
|
+ height: 32px;
|
|
|
+ border-radius: 6px;
|
|
|
+ overflow: hidden;
|
|
|
+ flex-shrink: 0;
|
|
|
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12);
|
|
|
+ background: #f0f0f0;
|
|
|
+}
|
|
|
+
|
|
|
+.message-avatar img {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ object-fit: cover;
|
|
|
+ transition: transform 0.3s ease;
|
|
|
+}
|
|
|
+
|
|
|
+.message-avatar:hover img {
|
|
|
+ transform: scale(1.1);
|
|
|
+}
|
|
|
+
|
|
|
+.message-wrapper-left .message-avatar {
|
|
|
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ flex-shrink: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.message-wrapper-right .message-avatar {
|
|
|
+ background: linear-gradient(135deg, #10b981 0%, #059669 100%);
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ flex-shrink: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.message-content {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ max-width: calc(100% - 42px);
|
|
|
+}
|
|
|
+
|
|
|
+.message-wrapper-left .message-content {
|
|
|
+ align-items: flex-start;
|
|
|
+ margin-left: 4px;
|
|
|
+}
|
|
|
+
|
|
|
+.message-wrapper-right .message-content {
|
|
|
+ align-items: flex-end !important;
|
|
|
+ margin-right: 4px;
|
|
|
+}
|
|
|
+
|
|
|
+/* 客户聊天内容容器 */
|
|
|
+.message-content-right {
|
|
|
+ flex: 0 0 auto !important;
|
|
|
+ max-width: calc(100% - 42px) !important;
|
|
|
+ display: flex;
|
|
|
+ align-items: flex-start !important;
|
|
|
+}
|
|
|
+
|
|
|
+.message-bubble {
|
|
|
+ background: white;
|
|
|
+ padding: 9px 13px;
|
|
|
+ border-radius: 6px;
|
|
|
+ font-size: 14px;
|
|
|
+ line-height: 1.5;
|
|
|
+ color: #0f172a;
|
|
|
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
|
|
|
+ word-break: break-word;
|
|
|
+ position: relative;
|
|
|
+ max-width: 500px;
|
|
|
+}
|
|
|
+
|
|
|
+.message-bubble::before {
|
|
|
+ content: '';
|
|
|
+ position: absolute;
|
|
|
+ left: -6px;
|
|
|
+ top: 12px;
|
|
|
+ width: 0;
|
|
|
+ height: 0;
|
|
|
+ border-top: 5px solid transparent;
|
|
|
+ border-bottom: 5px solid transparent;
|
|
|
+ border-right: 6px solid white;
|
|
|
+}
|
|
|
+
|
|
|
+.message-bubble-right {
|
|
|
+ background: #d9fdd3;
|
|
|
+ color: #0f172a;
|
|
|
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
|
|
|
+ display: inline-block;
|
|
|
+ position: relative;
|
|
|
+}
|
|
|
+
|
|
|
+.message-bubble-right::before {
|
|
|
+ content: '';
|
|
|
+ position: absolute;
|
|
|
+ right: -6px;
|
|
|
+ left: auto;
|
|
|
+ top: 16px !important;
|
|
|
+ transform: none !important;
|
|
|
+ width: 0;
|
|
|
+ height: 0;
|
|
|
+ border-top: 5px solid transparent;
|
|
|
+ border-bottom: 5px solid transparent;
|
|
|
+ border-left: 6px solid #d9fdd3;
|
|
|
+ border-right: none;
|
|
|
+}
|
|
|
+
|
|
|
+.empty-chat-tip {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ padding: 60px 20px;
|
|
|
+ color: #94a3b8;
|
|
|
+ font-size: 14px;
|
|
|
+}
|
|
|
+
|
|
|
+.empty-chat-tip i {
|
|
|
+ font-size: 48px;
|
|
|
+ margin-bottom: 12px;
|
|
|
+ opacity: 0.5;
|
|
|
+}
|
|
|
+
|
|
|
+/* 客户画像样式 */
|
|
|
+.profile-grid {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 4px;
|
|
|
+ max-height: 350px;
|
|
|
+ overflow-y: auto;
|
|
|
+ overflow-x: hidden;
|
|
|
+ padding-right: 4px;
|
|
|
+ padding-top: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.profile-grid::-webkit-scrollbar {
|
|
|
+ width: 6px;
|
|
|
+}
|
|
|
+
|
|
|
+.profile-grid::-webkit-scrollbar-track {
|
|
|
+ background: #f1f5f9;
|
|
|
+ border-radius: 3px;
|
|
|
+}
|
|
|
+
|
|
|
+.profile-grid::-webkit-scrollbar-thumb {
|
|
|
+ background: linear-gradient(180deg, #cbd5e1 0%, #94a3b8 100%);
|
|
|
+ border-radius: 3px;
|
|
|
+}
|
|
|
+
|
|
|
+.profile-grid::-webkit-scrollbar-thumb:hover {
|
|
|
+ background: linear-gradient(180deg, #94a3b8 0%, #64748b 100%);
|
|
|
+}
|
|
|
+
|
|
|
+.profile-item {
|
|
|
+ display: grid;
|
|
|
+ grid-template-columns: 42% 58%;
|
|
|
+ align-items: flex-start;
|
|
|
+ gap: 6px;
|
|
|
+ padding: 4px 10px;
|
|
|
+ border-radius: 6px;
|
|
|
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
|
+ background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
|
|
|
+ border: 1px solid #e2e8f0;
|
|
|
+ word-break: break-word;
|
|
|
+}
|
|
|
+
|
|
|
+.profile-item:hover {
|
|
|
+ background: linear-gradient(135deg, #f1f5f9 0%, #e2e8f0 100%);
|
|
|
+ transform: translateX(4px);
|
|
|
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06);
|
|
|
+ border-color: #cbd5e1;
|
|
|
+}
|
|
|
+
|
|
|
+.profile-item-main {
|
|
|
+ background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);
|
|
|
+ border-color: #bfdbfe;
|
|
|
+ position: sticky;
|
|
|
+ top: 0;
|
|
|
+ z-index: 10;
|
|
|
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
|
|
+}
|
|
|
+
|
|
|
+.profile-item-main:hover {
|
|
|
+ background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%);
|
|
|
+}
|
|
|
+
|
|
|
+.profile-item-full {
|
|
|
+ grid-template-columns: 42% 58%;
|
|
|
+}
|
|
|
+
|
|
|
+.profile-item .label {
|
|
|
+ font-size: 15px;
|
|
|
+ color: #64748b;
|
|
|
+ font-weight: 600;
|
|
|
+ white-space: normal;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 4px;
|
|
|
+ line-height: 1.4;
|
|
|
+ min-width: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.profile-item .label i {
|
|
|
+ color: #94a3b8;
|
|
|
+ font-size: 12px;
|
|
|
+ width: 14px;
|
|
|
+ text-align: center;
|
|
|
+ flex-shrink: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.profile-item .value {
|
|
|
+ font-size: 16px;
|
|
|
+ color: #0f172a;
|
|
|
+ font-weight: 500;
|
|
|
+ word-break: break-word;
|
|
|
+ line-height: 1.4;
|
|
|
+ min-width: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.profile-item .value.highlight {
|
|
|
+ color: #0369a1;
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: 600;
|
|
|
+}
|
|
|
+
|
|
|
+.profile-item .value.long-text {
|
|
|
+ color: #334155;
|
|
|
+ font-weight: 400;
|
|
|
+}
|
|
|
+
|
|
|
+.update-time-corner {
|
|
|
+ position: absolute;
|
|
|
+ bottom: 12px;
|
|
|
+ right: 16px;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #94a3b8;
|
|
|
+ font-style: italic;
|
|
|
+}
|
|
|
+
|
|
|
+/* 客户关注点 & 意向度样式 */
|
|
|
+.focus-points {
|
|
|
+ padding: 0;
|
|
|
+ margin-bottom: 10px;
|
|
|
+}
|
|
|
+
|
|
|
+.focus-title {
|
|
|
+ font-size: 17px;
|
|
|
+ color: #64748b;
|
|
|
+ font-weight: 600;
|
|
|
+ margin-bottom: 8px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 6px;
|
|
|
+}
|
|
|
+
|
|
|
+.focus-title i {
|
|
|
+ color: #3b82f6;
|
|
|
+ font-size: 14px;
|
|
|
+}
|
|
|
+
|
|
|
+.focus-list {
|
|
|
+ list-style: none;
|
|
|
+ padding: 0;
|
|
|
+ margin: 0;
|
|
|
+ max-height: 200px;
|
|
|
+ overflow-y: auto;
|
|
|
+ overflow-x: hidden;
|
|
|
+ padding-right: 4px;
|
|
|
+}
|
|
|
+
|
|
|
+.focus-list::-webkit-scrollbar {
|
|
|
+ width: 6px;
|
|
|
+}
|
|
|
+
|
|
|
+.focus-list::-webkit-scrollbar-track {
|
|
|
+ background: #f1f5f9;
|
|
|
+ border-radius: 3px;
|
|
|
+}
|
|
|
+
|
|
|
+.focus-list::-webkit-scrollbar-thumb {
|
|
|
+ background: linear-gradient(180deg, #cbd5e1 0%, #94a3b8 100%);
|
|
|
+ border-radius: 3px;
|
|
|
+}
|
|
|
+
|
|
|
+.focus-list::-webkit-scrollbar-thumb:hover {
|
|
|
+ background: linear-gradient(180deg, #94a3b8 0%, #64748b 100%);
|
|
|
+}
|
|
|
+
|
|
|
+.focus-item {
|
|
|
+ display: flex;
|
|
|
+ align-items: flex-start;
|
|
|
+ gap: 6px;
|
|
|
+ padding: 6px 10px;
|
|
|
+ margin-bottom: 6px;
|
|
|
+ background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
|
|
|
+ border-radius: 6px;
|
|
|
+ border: 1px solid #e2e8f0;
|
|
|
+ transition: all 0.3s ease;
|
|
|
+ font-size: 15px;
|
|
|
+ color: #334155;
|
|
|
+ line-height: 1.5;
|
|
|
+}
|
|
|
+
|
|
|
+.focus-item:hover {
|
|
|
+ background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);
|
|
|
+ border-color: #bfdbfe;
|
|
|
+ transform: translateX(4px);
|
|
|
+ box-shadow: 0 2px 6px rgba(59, 130, 246, 0.1);
|
|
|
+}
|
|
|
+
|
|
|
+.focus-item i {
|
|
|
+ color: #3b82f6;
|
|
|
+ font-size: 10px;
|
|
|
+ margin-top: 1px;
|
|
|
+ flex-shrink: 0;
|
|
|
+}
|
|
|
+
|
|
|
+/* 意向度样式 - 水印风格 */
|
|
|
+.intention-section {
|
|
|
+ margin-top: 10px;
|
|
|
+ padding-top: 8px;
|
|
|
+ border-top: 1px solid #e2e8f0;
|
|
|
+}
|
|
|
+
|
|
|
+.intention-header {
|
|
|
+ margin-bottom: 6px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 6px;
|
|
|
+}
|
|
|
+
|
|
|
+.intention-info-icon {
|
|
|
+ color: #94a3b8;
|
|
|
+ font-size: 16px;
|
|
|
+ cursor: pointer;
|
|
|
+ transition: all 0.3s ease;
|
|
|
+}
|
|
|
+
|
|
|
+.intention-info-icon:hover {
|
|
|
+ color: #3b82f6;
|
|
|
+}
|
|
|
+
|
|
|
+/* 意向度提示框样式 */
|
|
|
+.intention-tooltip {
|
|
|
+ line-height: 1.8;
|
|
|
+ font-size: 13px;
|
|
|
+}
|
|
|
+
|
|
|
+.intention-tooltip div {
|
|
|
+ padding: 2px 0;
|
|
|
+}
|
|
|
+
|
|
|
+.intention-tooltip strong {
|
|
|
+ color: #1e293b;
|
|
|
+ font-weight: 600;
|
|
|
+}
|
|
|
+
|
|
|
+.intention-label {
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #64748b;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 4px;
|
|
|
+}
|
|
|
+
|
|
|
+.intention-label::before {
|
|
|
+ content: '';
|
|
|
+ width: 3px;
|
|
|
+ height: 14px;
|
|
|
+ background: linear-gradient(180deg, #3b82f6 0%, #2563eb 100%);
|
|
|
+ border-radius: 2px;
|
|
|
+}
|
|
|
+
|
|
|
+/* 水印风格意向度显示 - 按等级着色 */
|
|
|
+.intention-watermark {
|
|
|
+ font-size: 59px;
|
|
|
+ font-weight: 800;
|
|
|
+ text-align: center;
|
|
|
+ padding: 18px 12px;
|
|
|
+ border-radius: 10px;
|
|
|
+ border: 2px solid;
|
|
|
+ position: relative;
|
|
|
+ overflow: hidden;
|
|
|
+ letter-spacing: 6px;
|
|
|
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
|
|
|
+ transition: all 0.3s ease;
|
|
|
+}
|
|
|
+
|
|
|
+/* A 级 - 金色/绿色,最高级别 */
|
|
|
+.intention-grade-a {
|
|
|
+ background: linear-gradient(135deg, #fef3c7 0%, #fde68a 50%, #fef3c7 100%);
|
|
|
+ border-color: #f59e0b;
|
|
|
+ color: #92400e;
|
|
|
+ text-shadow: 0 2px 4px rgba(146, 64, 14, 0.2);
|
|
|
+}
|
|
|
+
|
|
|
+.intention-grade-a::after {
|
|
|
+ content: 'A';
|
|
|
+ position: absolute;
|
|
|
+ top: 50%;
|
|
|
+ left: 50%;
|
|
|
+ transform: translate(-50%, -50%) rotate(-25deg);
|
|
|
+ font-size: 90px;
|
|
|
+ font-weight: 900;
|
|
|
+ color: rgba(245, 158, 11, 0.08);
|
|
|
+ z-index: 0;
|
|
|
+ pointer-events: none;
|
|
|
+}
|
|
|
+
|
|
|
+/* B 级 - 蓝色 */
|
|
|
+.intention-grade-b {
|
|
|
+ background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 50%, #dbeafe 100%);
|
|
|
+ border-color: #3b82f6;
|
|
|
+ color: #1e40af;
|
|
|
+ text-shadow: 0 2px 4px rgba(30, 64, 175, 0.2);
|
|
|
+}
|
|
|
+
|
|
|
+.intention-grade-b::after {
|
|
|
+ content: 'B';
|
|
|
+ position: absolute;
|
|
|
+ top: 50%;
|
|
|
+ left: 50%;
|
|
|
+ transform: translate(-50%, -50%) rotate(-25deg);
|
|
|
+ font-size: 90px;
|
|
|
+ font-weight: 900;
|
|
|
+ color: rgba(59, 130, 246, 0.08);
|
|
|
+ z-index: 0;
|
|
|
+ pointer-events: none;
|
|
|
+}
|
|
|
+
|
|
|
+/* C 级 - 紫色 */
|
|
|
+.intention-grade-c {
|
|
|
+ background: linear-gradient(135deg, #e9d5ff 0%, #d8b4fe 50%, #e9d5ff 100%);
|
|
|
+ border-color: #a855f7;
|
|
|
+ color: #6b21a8;
|
|
|
+ text-shadow: 0 2px 4px rgba(107, 33, 168, 0.2);
|
|
|
+}
|
|
|
+
|
|
|
+.intention-grade-c::after {
|
|
|
+ content: 'C';
|
|
|
+ position: absolute;
|
|
|
+ top: 50%;
|
|
|
+ left: 50%;
|
|
|
+ transform: translate(-50%, -50%) rotate(-25deg);
|
|
|
+ font-size: 90px;
|
|
|
+ font-weight: 900;
|
|
|
+ color: rgba(168, 85, 247, 0.08);
|
|
|
+ z-index: 0;
|
|
|
+ pointer-events: none;
|
|
|
+}
|
|
|
+
|
|
|
+/* D 级 - 橙色 */
|
|
|
+.intention-grade-d {
|
|
|
+ background: linear-gradient(135deg, #fed7aa 0%, #fdba74 50%, #fed7aa 100%);
|
|
|
+ border-color: #f97316;
|
|
|
+ color: #9a3412;
|
|
|
+ text-shadow: 0 2px 4px rgba(154, 52, 18, 0.2);
|
|
|
+}
|
|
|
+
|
|
|
+.intention-grade-d::after {
|
|
|
+ content: 'D';
|
|
|
+ position: absolute;
|
|
|
+ top: 50%;
|
|
|
+ left: 50%;
|
|
|
+ transform: translate(-50%, -50%) rotate(-25deg);
|
|
|
+ font-size: 90px;
|
|
|
+ font-weight: 900;
|
|
|
+ color: rgba(249, 115, 22, 0.08);
|
|
|
+ z-index: 0;
|
|
|
+ pointer-events: none;
|
|
|
+}
|
|
|
+
|
|
|
+/* E 级 - 粉红色 */
|
|
|
+.intention-grade-e {
|
|
|
+ background: linear-gradient(135deg, #fbcfe8 0%, #f9a8d4 50%, #fbcfe8 100%);
|
|
|
+ border-color: #ec4899;
|
|
|
+ color: #9d174d;
|
|
|
+ text-shadow: 0 2px 4px rgba(157, 23, 77, 0.2);
|
|
|
+}
|
|
|
+
|
|
|
+.intention-grade-e::after {
|
|
|
+ content: 'E';
|
|
|
+ position: absolute;
|
|
|
+ top: 50%;
|
|
|
+ left: 50%;
|
|
|
+ transform: translate(-50%, -50%) rotate(-25deg);
|
|
|
+ font-size: 90px;
|
|
|
+ font-weight: 900;
|
|
|
+ color: rgba(236, 72, 153, 0.08);
|
|
|
+ z-index: 0;
|
|
|
+ pointer-events: none;
|
|
|
+}
|
|
|
+
|
|
|
+/* F 级 - 红色,最低级别 */
|
|
|
+.intention-grade-f {
|
|
|
+ background: linear-gradient(135deg, #fecaca 0%, #fca5a5 50%, #fecaca 100%);
|
|
|
+ border-color: #ef4444;
|
|
|
+ color: #991b1b;
|
|
|
+ text-shadow: 0 2px 4px rgba(153, 27, 27, 0.2);
|
|
|
+}
|
|
|
+
|
|
|
+.intention-grade-f::after {
|
|
|
+ content: 'F';
|
|
|
+ position: absolute;
|
|
|
+ top: 50%;
|
|
|
+ left: 50%;
|
|
|
+ transform: translate(-50%, -50%) rotate(-25deg);
|
|
|
+ font-size: 90px;
|
|
|
+ font-weight: 900;
|
|
|
+ color: rgba(239, 68, 68, 0.08);
|
|
|
+ z-index: 0;
|
|
|
+ pointer-events: none;
|
|
|
+}
|
|
|
+
|
|
|
+.intention-watermark span {
|
|
|
+ position: relative;
|
|
|
+ z-index: 1;
|
|
|
+}
|
|
|
+
|
|
|
+/* 暂无评级提示 */
|
|
|
+.no-intention-tip {
|
|
|
+ text-align: center;
|
|
|
+ padding: 18px 12px;
|
|
|
+ font-size: 16px;
|
|
|
+ color: #94a3b8;
|
|
|
+ font-style: italic;
|
|
|
+ background: linear-gradient(135deg, rgba(248, 250, 252, 0.5) 0%, rgba(241, 245, 249, 0.5) 100%);
|
|
|
+ border-radius: 10px;
|
|
|
+ border: 2px dashed #e2e8f0;
|
|
|
+}
|
|
|
+
|
|
|
+.card-header h3 i {
|
|
|
+ font-size: 20px;
|
|
|
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
|
+ -webkit-background-clip: text;
|
|
|
+ -webkit-text-fill-color: transparent;
|
|
|
+ background-clip: text;
|
|
|
+}
|
|
|
+
|
|
|
+.card-highlight .card-header h3 i {
|
|
|
+ color: white;
|
|
|
+ background: none;
|
|
|
+ -webkit-text-fill-color: white;
|
|
|
+}
|
|
|
+
|
|
|
+/* 统一为 CRM 客户分析报告风格(覆盖) */
|
|
|
+.customer-container {
|
|
|
+ max-width: 100%;
|
|
|
+ padding: 12px;
|
|
|
+ background: #f4f6fa;
|
|
|
+}
|
|
|
+
|
|
|
+.main-grid-three-columns {
|
|
|
+ grid-template-columns: 300px minmax(640px, 1fr) 320px;
|
|
|
+ gap: 12px;
|
|
|
+ align-items: start;
|
|
|
+}
|
|
|
+
|
|
|
+.card {
|
|
|
+ border-radius: 10px;
|
|
|
+ border: 1px solid #e6ebf2;
|
|
|
+ box-shadow: 0 1px 3px rgba(15, 23, 42, 0.06);
|
|
|
+ margin-bottom: 10px;
|
|
|
+ padding: 12px;
|
|
|
+ background: #fff;
|
|
|
+}
|
|
|
+
|
|
|
+.card::before {
|
|
|
+ display: none;
|
|
|
+}
|
|
|
+
|
|
|
+.card:hover {
|
|
|
+ transform: none;
|
|
|
+ box-shadow: 0 2px 8px rgba(15, 23, 42, 0.08);
|
|
|
+ border-color: #dbe4f0;
|
|
|
+}
|
|
|
+
|
|
|
+.card-header {
|
|
|
+ border-bottom: 1px solid #edf1f7;
|
|
|
+ margin-bottom: 10px;
|
|
|
+ padding-bottom: 8px;
|
|
|
+}
|
|
|
+
|
|
|
+.card-header h3 {
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #1f2937;
|
|
|
+}
|
|
|
+
|
|
|
+.card-header h3 i {
|
|
|
+ width: 18px;
|
|
|
+ height: 18px;
|
|
|
+ border-radius: 4px;
|
|
|
+ font-size: 10px;
|
|
|
+ background: #4f7cff;
|
|
|
+ box-shadow: none;
|
|
|
+ -webkit-text-fill-color: #fff;
|
|
|
+}
|
|
|
+
|
|
|
+.summary-text.compact {
|
|
|
+ font-size: 14px;
|
|
|
+ line-height: 1.75;
|
|
|
+ color: #334155;
|
|
|
+ max-height: 132px;
|
|
|
+}
|
|
|
+
|
|
|
+.risk-card,
|
|
|
+.card-focus {
|
|
|
+ background: #fff;
|
|
|
+ border: 1px solid #e6ebf2;
|
|
|
+}
|
|
|
+
|
|
|
+.risk-analysis {
|
|
|
+ background: #f8fafc;
|
|
|
+ border: 1px solid #edf2f7;
|
|
|
+}
|
|
|
+
|
|
|
+/* 风险徽章改为标签风格 */
|
|
|
+.risk-badge {
|
|
|
+ display: inline-flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 6px;
|
|
|
+ padding: 5px 10px;
|
|
|
+ border-radius: 10px;
|
|
|
+ font-size: 13px;
|
|
|
+ font-weight: 600;
|
|
|
+ border: 1px solid #e5eaf1;
|
|
|
+ box-shadow: none;
|
|
|
+ transition: all 0.2s ease;
|
|
|
+ text-shadow: none;
|
|
|
+}
|
|
|
+
|
|
|
+.risk-badge::before {
|
|
|
+ content: '';
|
|
|
+ width: 8px;
|
|
|
+ height: 8px;
|
|
|
+ border-radius: 3px;
|
|
|
+ background: currentColor;
|
|
|
+ opacity: 0.35;
|
|
|
+}
|
|
|
+
|
|
|
+.risk-card:hover .risk-badge {
|
|
|
+ transform: translateY(-1px);
|
|
|
+}
|
|
|
+
|
|
|
+.risk-unknown .risk-badge {
|
|
|
+ background: #f8fafc;
|
|
|
+ border-color: #e5eaf1;
|
|
|
+ color: #64748b;
|
|
|
+}
|
|
|
+
|
|
|
+.risk-none .risk-badge {
|
|
|
+ background: #f0fdf4;
|
|
|
+ border-color: #bbf7d0;
|
|
|
+ color: #16a34a;
|
|
|
+}
|
|
|
+
|
|
|
+.risk-low .risk-badge {
|
|
|
+ background: #eff6ff;
|
|
|
+ border-color: #bfdbfe;
|
|
|
+ color: #2563eb;
|
|
|
+}
|
|
|
+
|
|
|
+.risk-medium .risk-badge {
|
|
|
+ background: #fffbeb;
|
|
|
+ border-color: #fde68a;
|
|
|
+ color: #d97706;
|
|
|
+}
|
|
|
+
|
|
|
+.risk-high .risk-badge {
|
|
|
+ background: #fef2f2;
|
|
|
+ border-color: #fecaca;
|
|
|
+ color: #dc2626;
|
|
|
+}
|
|
|
+
|
|
|
+/* 客户意向度:回滚为原来的“大水印渐变”样式(使用上方原始定义) */
|
|
|
+
|
|
|
+.tag-item,
|
|
|
+.focus-item,
|
|
|
+.profile-item {
|
|
|
+ background: #f8fafc;
|
|
|
+ border-color: #e5eaf1;
|
|
|
+}
|
|
|
+
|
|
|
+.records-table th {
|
|
|
+ background: #f8fafc;
|
|
|
+ color: #475569;
|
|
|
+}
|
|
|
+
|
|
|
+.records-table tbody tr:hover {
|
|
|
+ background: #f8fbff;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+</style>
|