finyx_data_ai/tests/test_scenario_recommendation.html
2026-01-11 07:48:19 +08:00

919 lines
43 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>潜在场景推荐接口测试 - Finyx Data AI</title>
<link rel="stylesheet" href="test_common.css">
<style>
.scenario-card {
border: 1px solid var(--border-color);
border-radius: var(--radius);
padding: 20px;
margin-bottom: 16px;
transition: var(--transition);
position: relative;
}
.scenario-card:hover {
border-color: var(--primary-color);
box-shadow: var(--shadow);
transform: translateY(-2px);
}
.scenario-header {
display: flex;
justify-content: space-between;
align-items: start;
margin-bottom: 12px;
}
.scenario-title {
font-size: 16px;
font-weight: 600;
color: var(--dark-color);
flex: 1;
}
.scenario-type {
display: inline-block;
padding: 4px 12px;
border-radius: 12px;
font-size: 11px;
font-weight: 500;
background-color: #e3f2fd;
color: #1976d2;
margin-left: 8px;
}
.scenario-rating {
display: flex;
align-items: center;
margin-bottom: 12px;
}
.star {
color: #ffc107;
font-size: 16px;
}
.star-empty {
color: #e0e0e0;
}
.rating-text {
margin-left: 8px;
font-size: 12px;
color: var(--text-muted);
}
.scenario-desc {
font-size: 13px;
color: var(--text-color);
line-height: 1.6;
margin-bottom: 12px;
}
.scenario-meta {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
padding-top: 12px;
border-top: 1px solid var(--border-color);
}
.meta-item {
font-size: 12px;
}
.meta-label {
color: var(--text-muted);
font-weight: 500;
}
.meta-value {
color: var(--dark-color);
margin-top: 2px;
}
.roi-badge {
display: inline-block;
padding: 4px 8px;
border-radius: 4px;
font-size: 11px;
font-weight: 500;
}
.roi-high { background-color: #e8f5e9; color: #2e7d32; }
.roi-medium { background-color: #fff3e0; color: #ef6c00; }
.roi-low { background-color: #ffebee; color: #c62828; }
.tag-list {
display: flex;
flex-wrap: wrap;
gap: 4px;
margin-top: 8px;
}
.tag {
display: inline-block;
padding: 2px 8px;
border-radius: 4px;
font-size: 11px;
background-color: var(--light-color);
color: var(--text-muted);
}
</style>
</head>
<body>
<div class="container">
<!-- 页面头部 -->
<header class="page-header">
<h1 class="page-title">💡 潜在场景推荐接口测试</h1>
<p class="page-subtitle">
基于企业背景、数据资产清单和存量场景,使用 AI 推荐潜在的数据应用场景
</p>
</header>
<div class="content-grid">
<!-- 左侧:输入表单 -->
<div class="col-4">
<div class="card">
<div class="card-header">
<h3 class="card-title">输入参数</h3>
</div>
<div class="card-body">
<form id="recommendForm">
<div class="form-group">
<label class="form-label" for="projectId">项目ID *</label>
<input type="text" id="projectId" class="form-control" value="project_001" placeholder="输入项目ID">
</div>
<!-- 企业信息 -->
<div class="form-group">
<label class="form-label">企业信息</label>
<select id="industry" class="form-control" style="margin-bottom: 8px;">
<option value="">请选择行业</option>
<option value="retail-fresh" selected>零售生鲜</option>
<option value="retail-general">零售通用</option>
<option value="finance">金融</option>
<option value="healthcare">医疗健康</option>
<option value="logistics">物流</option>
<option value="manufacturing">制造业</option>
</select>
<textarea id="companyDesc" class="form-control" rows="3" placeholder="企业描述">某连锁生鲜零售企业主营水果、蔬菜等生鲜产品拥有200+线下门店和线上电商平台</textarea>
<select id="dataScale" class="form-control" style="margin-top: 8px;">
<option value="">请选择数据规模</option>
<option value="10TB" selected>10TB</option>
<option value="50TB">50TB</option>
<option value="100TB">100TB</option>
<option value="500TB">500TB</option>
<option value="1PB">1PB+</option>
</select>
</div>
<!-- 数据资产 -->
<div class="form-group">
<label class="form-label">快速配置数据资产</label>
<div class="btn-group">
<button type="button" class="btn btn-info btn-sm" onclick="loadDataAssets('retail')">零售场景</button>
<button type="button" class="btn btn-info btn-sm" onclick="loadDataAssets('finance')">金融场景</button>
<button type="button" class="btn btn-info btn-sm" onclick="loadDataAssets('user')">用户中心</button>
</div>
<div id="assetsList" style="margin-top: 12px; max-height: 200px; overflow-y: auto;">
<!-- 动态加载 -->
</div>
</div>
<!-- 存量场景 -->
<div class="form-group">
<label class="form-label">存量场景(避免重复推荐)</label>
<div id="existingScenariosList" style="margin-top: 8px;">
<!-- 动态加载 -->
</div>
<button type="button" class="btn btn-outline btn-sm" style="margin-top: 8px;" onclick="addExistingScenario()">+ 添加场景</button>
</div>
<!-- 配置选项 -->
<div class="form-group">
<label class="form-label">推荐配置</label>
<div class="form-row">
<select id="model" class="form-control">
<option value="qwen-max" selected>通义千问 Max</option>
<option value="gpt-4">GPT-4</option>
</select>
<input type="number" id="recommendationCount" class="form-control" value="10" min="1" max="20" title="推荐数量">
</div>
<div style="margin-top: 8px;">
<label>
<input type="checkbox" id="excludeDuplicate"> 排除重复场景类型
</label>
</div>
</div>
<div class="btn-group" style="margin-top: 20px;">
<button type="submit" class="btn btn-primary">🚀 生成推荐</button>
<button type="button" class="btn btn-outline" onclick="resetForm()">重置</button>
</div>
</form>
</div>
</div>
<!-- API 调用信息 -->
<div class="card">
<div class="card-header">
<h3 class="card-title">API 调用信息</h3>
</div>
<div class="card-body">
<div class="form-group">
<label class="form-label">请求端点</label>
<code style="display: block; padding: 8px; background: var(--light-color); border-radius: var(--radius); font-size: 12px;">
POST /api/v1/value/scenario-recommendation
</code>
</div>
<div id="requestInfo" class="form-group">
<label class="form-label">请求数据</label>
<pre id="requestJson" style="max-height: 200px; overflow: auto; font-size: 11px; background: var(--light-color); padding: 8px; border-radius: var(--radius);">等待提交...</pre>
</div>
<div id="responseInfo" class="form-group" style="display: none;">
<label class="form-label">响应数据</label>
<pre id="responseJson" style="max-height: 300px; overflow: auto; font-size: 11px; background: var(--light-color); padding: 8px; border-radius: var(--radius);"></pre>
</div>
</div>
</div>
</div>
<!-- 右侧:结果展示 -->
<div class="col-8">
<!-- 加载状态 -->
<div id="loadingArea" style="display: none;"></div>
<!-- 结果区域 -->
<div id="resultArea" style="display: none;">
<!-- 推荐统计 -->
<div class="stats-grid">
<div class="stat-card">
<div class="stat-label">推荐场景数</div>
<div class="stat-value" id="statCount">0</div>
</div>
<div class="stat-card success">
<div class="stat-label">高推荐指数</div>
<div class="stat-value" id="statHigh">0</div>
</div>
<div class="stat-card warning">
<div class="stat-label">中等推荐指数</div>
<div class="stat-value" id="statMedium">0</div>
</div>
<div class="stat-card">
<div class="stat-label">低推荐指数</div>
<div class="stat-value" id="statLow">0</div>
</div>
<div class="stat-card info">
<div class="stat-label">生成耗时</div>
<div class="stat-value" id="statTime">0s</div>
</div>
</div>
<!-- 场景类型分布 -->
<div class="card">
<div class="card-header">
<h3 class="card-title">📊 场景类型分布</h3>
</div>
<div class="card-body">
<div id="scenarioTypeChart"></div>
</div>
</div>
<!-- ROI 分布 -->
<div class="card">
<div class="card-header">
<h3 class="card-title">💰 预估 ROI 分布</h3>
</div>
<div class="card-body">
<div id="roiChart"></div>
</div>
</div>
<!-- 推荐场景列表 -->
<div class="card">
<div class="card-header">
<h3 class="card-title">💡 推荐场景列表</h3>
</div>
<div class="card-body">
<div id="scenarioResults"></div>
</div>
</div>
</div>
<!-- 空状态 -->
<div id="emptyState" class="card" style="text-align: center; padding: 60px 20px;">
<div style="font-size: 48px; margin-bottom: 20px;">💡</div>
<h3 style="margin-bottom: 12px;">等待生成推荐</h3>
<p style="color: var(--text-muted);">
填写企业信息和数据资产配置<br>
点击"生成推荐"按钮获取潜在场景推荐
</p>
</div>
</div>
</div>
</div>
<script src="base_test_framework.js"></script>
<script>
// ==================== 虚拟数据 ====================
let currentDataAssets = [];
let existingScenarios = [];
const mockDataAssets = {
retail: [
{
name: '消费者全景画像',
core_tables: ['Dim_Customer', 'Fact_Sales', 'Dim_Product'],
description: '核心依赖客户维度表、销售事实表、商品维度表'
},
{
name: '全渠道销售数据',
core_tables: ['Fact_Sales', 'Dim_Store', 'Dim_Channel'],
description: '线上线下全渠道销售交易数据'
},
{
name: '会员权益数据',
core_tables: ['Dim_Member', 'Fact_Member_Point', 'Fact_Member_Coupon'],
description: '会员等级、积分、优惠券等权益数据'
},
{
name: '供应链库存数据',
core_tables: ['Dim_Product', 'Fact_Inventory', 'Fact_Purchase'],
description: '商品库存、采购、供应链流转数据'
}
],
finance: [
{
name: '客户账户数据',
core_tables: ['Dim_Customer', 'Fact_Account', 'Fact_Transaction'],
description: '客户基础信息、账户余额、交易记录'
},
{
name: '风险管理数据',
core_tables: ['Dim_Customer', 'Fact_Transaction', 'Fact_Credit_Record'],
description: '客户信用记录、风险评分数据'
},
{
name: '理财产品数据',
core_tables: ['Dim_Product', 'Fact_Investment', 'Fact_Rate'],
description: '理财产品、投资记录、收益率数据'
}
],
user: [
{
name: '用户基础信息',
core_tables: ['Dim_User', 'Dim_User_Profile', 'Fact_User_Login'],
description: '用户注册信息、个人资料、登录日志'
},
{
name: '用户行为数据',
core_tables: ['Fact_User_Behavior', 'Dim_User', 'Dim_Action'],
description: '用户浏览、点击、购买等行为数据'
},
{
name: '用户权限数据',
core_tables: ['Dim_User', 'Dim_Role', 'Fact_User_Role'],
description: '用户角色、权限分配数据'
}
]
};
const mockExistingScenarios = {
retail: [
{ name: '月度销售经营报表', description: '统计各区域门店的月度GMV维度单一' },
{ name: '会员等级统计', description: '展示各会员等级的数量分布' },
{ name: '商品销售排行榜', description: '按销售额展示商品排名' }
],
finance: [
{ name: '客户资产总览', description: '展示客户总资产分布情况' },
{ name: '交易流水查询', description: '提供交易流水查询功能' }
],
user: [
{ name: '用户登录统计', description: '统计用户登录次数和活跃度' },
{ name: '用户增长趋势', description: '展示用户注册增长趋势' }
]
};
const mockScenarios = {
retail: [
{
id: 1,
name: '精准会员营销',
type: '营销增长',
recommendation_index: 5,
desc: '基于用户画像和行为数据,实现千人千面的精准营销推送,提升转化率和复购率',
dependencies: ['消费者全景画像', '全渠道销售数据', '会员权益数据'],
business_value: '提升营销ROI 30%以上,显著增加用户粘性和复购率',
implementation_difficulty: '中等',
estimated_roi: '高',
technical_requirements: ['机器学习模型', '实时推荐引擎', '用户画像系统'],
data_requirements: ['用户行为数据', '交易数据', '产品数据']
},
{
id: 2,
name: '智能库存补货',
type: '降本增效',
recommendation_index: 5,
desc: '基于历史销售数据和季节性因素,预测未来需求,自动生成补货建议',
dependencies: ['供应链库存数据', '全渠道销售数据'],
business_value: '降低库存成本15-20%,减少缺货率,提升资金周转效率',
implementation_difficulty: '中等',
estimated_roi: '高',
technical_requirements: ['时间序列预测', '库存优化算法', '自动化补货系统'],
data_requirements: ['销售数据', '库存数据', '采购数据']
},
{
id: 3,
name: '价格弹性分析',
type: '营销增长',
recommendation_index: 4,
desc: '分析价格变化对销量的影响,优化定价策略,最大化利润',
dependencies: ['全渠道销售数据', '供应链库存数据'],
business_value: '提升利润率5-10%,优化价格竞争力',
implementation_difficulty: '高等',
estimated_roi: '中',
technical_requirements: ['价格弹性模型', '动态定价系统', '竞争分析工具'],
data_requirements: ['销售数据', '价格数据', '市场数据']
},
{
id: 4,
name: '客户流失预警',
type: '降本增效',
recommendation_index: 5,
desc: '通过用户行为分析,识别潜在流失风险用户,及时干预挽留',
dependencies: ['消费者全景画像', '会员权益数据', '全渠道销售数据'],
business_value: '降低流失率20-30%,提升客户终身价值',
implementation_difficulty: '高等',
estimated_roi: '高',
technical_requirements: ['流失预测模型', '用户行为分析', '营销自动化'],
data_requirements: ['用户行为数据', '会员数据', '交易数据']
},
{
id: 5,
name: '关联商品推荐',
type: '营销增长',
recommendation_index: 4,
desc: '基于购买关联分析,推荐相关商品,提升客单价',
dependencies: ['全渠道销售数据', '消费者全景画像'],
business_value: '提升客单价15-25%,增加交叉销售机会',
implementation_difficulty: '中等',
estimated_roi: '中',
technical_requirements: ['关联规则挖掘', '推荐算法', '实时计算引擎'],
data_requirements: ['交易数据', '商品数据', '用户数据']
},
{
id: 6,
name: '门店选址优化',
type: '降本增效',
recommendation_index: 4,
desc: '基于人口密度、消费水平、竞争环境等数据,优化门店选址',
dependencies: ['全渠道销售数据', '消费者全景画像'],
business_value: '降低选址风险,提升新店成功率',
implementation_difficulty: '高等',
estimated_roi: '中',
technical_requirements: ['地理信息系统', '空间分析', '预测模型'],
data_requirements: ['销售数据', '人口数据', '市场数据']
},
{
id: 7,
name: '智能客服',
type: '降本增效',
recommendation_index: 3,
desc: '基于自然语言处理,提供智能客服,降低人力成本',
dependencies: ['消费者全景画像'],
business_value: '降低客服成本40%以上,提升服务效率',
implementation_difficulty: '中等',
estimated_roi: '中',
technical_requirements: ['NLP技术', '知识图谱', '对话系统'],
data_requirements: ['用户数据', '知识库', '客服日志']
},
{
id: 8,
name: '生鲜损耗控制',
type: '降本增效',
recommendation_index: 5,
desc: '预测生鲜商品的损耗,优化订货和存储策略,减少浪费',
dependencies: ['供应链库存数据', '全渠道销售数据'],
business_value: '降低损耗率15-25%,直接节省成本',
implementation_difficulty: '中等',
estimated_roi: '高',
technical_requirements: ['损耗预测模型', '库存管理系统', '物联网监控'],
data_requirements: ['库存数据', '销售数据', '环境数据']
},
{
id: 9,
name: '会员生命周期管理',
type: '营销增长',
recommendation_index: 4,
desc: '对会员进行生命周期分群,制定差异化运营策略',
dependencies: ['消费者全景画像', '会员权益数据', '全渠道销售数据'],
business_value: '提升会员活跃度和忠诚度,延长生命周期',
implementation_difficulty: '中等',
estimated_roi: '中',
technical_requirements: ['生命周期模型', '用户分群', '营销自动化'],
data_requirements: ['会员数据', '交易数据', '行为数据']
},
{
id: 10,
name: '全渠道库存统一',
type: '降本增效',
recommendation_index: 4,
desc: '实现线上线下库存统一管理,提升库存周转效率',
dependencies: ['供应链库存数据', '全渠道销售数据'],
business_value: '提升库存周转率20-30%,减少缺货',
implementation_difficulty: '高等',
estimated_roi: '中',
technical_requirements: ['库存管理系统', '实时同步', '订单管理系统'],
data_requirements: ['库存数据', '销售数据', '订单数据']
}
],
finance: [
{
id: 1,
name: '智能风控',
type: '风险管理',
recommendation_index: 5,
desc: '基于机器学习模型,实时评估交易风险,降低欺诈率',
dependencies: ['客户账户数据', '风险管理数据'],
business_value: '降低欺诈损失30-50%,提升风控效率',
implementation_difficulty: '高等',
estimated_roi: '高',
technical_requirements: ['机器学习', '实时计算', '规则引擎'],
data_requirements: ['交易数据', '客户数据', '风险数据']
},
{
id: 2,
name: '理财产品推荐',
type: '营销增长',
recommendation_index: 4,
desc: '基于客户风险偏好和资产情况,推荐合适的理财产品',
dependencies: ['客户账户数据', '理财产品数据'],
business_value: '提升理财销售额20-30%,增强客户粘性',
implementation_difficulty: '中等',
estimated_roi: '中',
technical_requirements: ['推荐算法', '客户画像', '产品匹配引擎'],
data_requirements: ['客户数据', '产品数据', '交易数据']
},
{
id: 3,
name: '客户分群画像',
type: '营销增长',
recommendation_index: 3,
desc: '对客户进行精细化分群,制定差异化营销策略',
dependencies: ['客户账户数据', '风险管理数据'],
business_value: '提升营销精准度,降低营销成本',
implementation_difficulty: '中等',
estimated_roi: '中',
technical_requirements: ['客户画像', '聚类算法', '数据可视化'],
data_requirements: ['客户数据', '交易数据', '行为数据']
}
],
user: [
{
id: 1,
name: '用户行为分析',
type: '数据分析',
recommendation_index: 4,
desc: '深入分析用户行为路径,识别关键转化点',
dependencies: ['用户基础信息', '用户行为数据'],
business_value: '优化产品体验,提升转化率',
implementation_difficulty: '中等',
estimated_roi: '中',
technical_requirements: ['行为分析工具', '漏斗分析', '路径分析'],
data_requirements: ['行为数据', '用户数据', '事件数据']
},
{
id: 2,
name: '个性化推荐',
type: '营销增长',
recommendation_index: 5,
desc: '基于用户行为和偏好,提供个性化内容推荐',
dependencies: ['用户基础信息', '用户行为数据', '用户权限数据'],
business_value: '提升用户活跃度和留存率',
implementation_difficulty: '中等',
estimated_roi: '高',
technical_requirements: ['推荐算法', '用户画像', '实时计算'],
data_requirements: ['行为数据', '用户数据', '内容数据']
},
{
id: 3,
name: '用户增长预测',
type: '数据分析',
recommendation_index: 3,
desc: '预测未来用户增长趋势,为产品决策提供依据',
dependencies: ['用户基础信息', '用户行为数据'],
business_value: '优化运营策略,提升获客效率',
implementation_difficulty: '中等',
estimated_roi: '中',
technical_requirements: ['预测模型', '时间序列', '数据可视化'],
data_requirements: ['用户数据', '注册数据', '活跃数据']
}
]
};
// ==================== 表单处理 ====================
// 加载数据资产
function loadDataAssets(type) {
currentDataAssets = mockDataAssets[type] || [];
existingScenarios = mockExistingScenarios[type] || [];
// 更新行业选择
document.getElementById('industry').value = {
'retail': 'retail-fresh',
'finance': 'finance',
'user': 'retail-general'
}[type];
// 更新企业描述
document.getElementById('companyDesc').value = {
'retail': '某连锁生鲜零售企业主营水果、蔬菜等生鲜产品拥有200+线下门店和线上电商平台',
'finance': '某银行机构,提供个人和企业金融服务',
'user': '互联网用户中心系统,负责用户注册、登录、权限管理等核心功能'
}[type];
// 渲染数据资产列表
renderAssetsList();
// 渲染存量场景列表
renderExistingScenariosList();
showToast(`已加载${{ 'retail': '零售', 'finance': '金融', 'user': '用户中心' }[type]}场景配置`);
}
// 渲染数据资产列表
function renderAssetsList() {
const container = document.getElementById('assetsList');
if (currentDataAssets.length === 0) {
container.innerHTML = '<p style="text-align: center; color: var(--text-muted); padding: 12px;">暂无数据资产</p>';
return;
}
let html = '';
currentDataAssets.forEach((asset, index) => {
html += `
<div style="padding: 8px 12px; background: var(--light-color); border-radius: var(--radius); margin-bottom: 8px;">
<div style="font-weight: 500; font-size: 13px; margin-bottom: 4px;">${asset.name}</div>
<div style="font-size: 11px; color: var(--text-muted); margin-bottom: 4px;">${asset.description}</div>
<div style="font-size: 11px;">
<span style="color: var(--info-color);">核心表:</span> ${asset.core_tables.join(', ')}
</div>
</div>
`;
});
container.innerHTML = html;
}
// 渲染存量场景列表
function renderExistingScenariosList() {
const container = document.getElementById('existingScenariosList');
if (existingScenarios.length === 0) {
container.innerHTML = '<p style="text-align: center; color: var(--text-muted); padding: 12px;">暂无存量场景</p>';
return;
}
let html = '';
existingScenarios.forEach((scenario, index) => {
html += `
<div style="display: flex; align-items: center; padding: 8px 12px; background: var(--light-color); border-radius: var(--radius); margin-bottom: 8px;">
<div style="flex: 1;">
<div style="font-weight: 500; font-size: 13px;">${scenario.name}</div>
<div style="font-size: 11px; color: var(--text-muted);">${scenario.description}</div>
</div>
<button type="button" onclick="removeExistingScenario(${index})" style="background: none; border: none; color: var(--danger-color); cursor: pointer; font-size: 18px;">×</button>
</div>
`;
});
container.innerHTML = html;
}
// 添加存量场景
function addExistingScenario() {
const name = prompt('请输入存量场景名称:');
if (!name) return;
const description = prompt('请输入场景描述:') || '';
existingScenarios.push({ name, description });
renderExistingScenariosList();
}
// 移除存量场景
function removeExistingScenario(index) {
existingScenarios.splice(index, 1);
renderExistingScenariosList();
}
// 重置表单
function resetForm() {
document.getElementById('recommendForm').reset();
currentDataAssets = [];
existingScenarios = [];
renderAssetsList();
renderExistingScenariosList();
document.getElementById('resultArea').style.display = 'none';
document.getElementById('emptyState').style.display = 'block';
document.getElementById('requestInfo').style.display = 'block';
document.getElementById('responseInfo').style.display = 'none';
}
// 表单提交
document.getElementById('recommendForm').addEventListener('submit', async function(e) {
e.preventDefault();
if (currentDataAssets.length === 0) {
showToast('请先配置数据资产');
return;
}
// 获取表单数据
const requestData = {
project_id: document.getElementById('projectId').value,
company_info: {
industry: [document.getElementById('industry').value],
description: document.getElementById('companyDesc').value,
data_scale: document.getElementById('dataScale').value,
data_sources: ['self-generated']
},
data_assets: currentDataAssets,
existing_scenarios: existingScenarios,
options: {
model: document.getElementById('model').value,
recommendation_count: parseInt(document.getElementById('recommendationCount').value),
exclude_types: document.getElementById('excludeDuplicate').checked ? ['duplicate'] : []
}
};
// 显示请求数据
document.getElementById('requestJson').textContent = JSON.stringify(requestData, null, 2);
document.getElementById('responseInfo').style.display = 'none';
// 显示加载状态
document.getElementById('emptyState').style.display = 'none';
document.getElementById('resultArea').style.display = 'none';
showLoading('loadingArea');
try {
// 模拟API调用
await delay(2500);
// 确定场景类型
const scenarioType = requestData.company_info.industry[0].includes('retail') ? 'retail' :
(requestData.company_info.industry[0].includes('finance') ? 'finance' : 'user');
// 生成模拟响应
const response = generateMockResponse(requestData, scenarioType);
// 显示结果
hideLoading('loadingArea', '');
document.getElementById('resultArea').style.display = 'block';
// 显示响应数据
document.getElementById('responseInfo').style.display = 'block';
document.getElementById('responseJson').textContent = JSON.stringify(response, null, 2);
// 渲染统计信息
renderStatistics(response);
// 渲染图表
renderCharts(response);
// 渲染场景列表
renderScenarioList(response.recommended_scenarios);
showSuccess('loadingArea', '✅ 推荐生成完成!');
setTimeout(() => {
document.getElementById('loadingArea').style.display = 'none';
}, 2000);
} catch (error) {
hideLoading('loadingArea', '');
showError('loadingArea', error.message);
}
});
// 生成模拟响应
function generateMockResponse(requestData, scenarioType) {
const scenarios = mockScenarios[scenarioType] || [];
const count = Math.min(requestData.options.recommendation_count, scenarios.length);
const selectedScenarios = scenarios.slice(0, count);
let highCount = 0;
let mediumCount = 0;
let lowCount = 0;
let typeCount = {};
let roiCount = { high: 0, medium: 0, low: 0 };
selectedScenarios.forEach(scenario => {
if (scenario.recommendation_index >= 5) highCount++;
else if (scenario.recommendation_index >= 3) mediumCount++;
else lowCount++;
typeCount[scenario.type] = (typeCount[scenario.type] || 0) + 1;
if (scenario.estimated_roi === '高') roiCount.high++;
else if (scenario.estimated_roi === '中') roiCount.medium++;
else roiCount.low++;
});
return {
recommended_scenarios: selectedScenarios,
total_count: selectedScenarios.length,
generation_time: (Math.random() * 2 + 1).toFixed(2),
model_used: requestData.options.model,
typeCount: typeCount,
roiCount: roiCount,
ratingCount: { high: highCount, medium: mediumCount, low: lowCount }
};
}
// 渲染统计信息
function renderStatistics(response) {
document.getElementById('statCount').textContent = response.total_count;
document.getElementById('statHigh').textContent = response.ratingCount.high;
document.getElementById('statMedium').textContent = response.ratingCount.medium;
document.getElementById('statLow').textContent = response.ratingCount.low;
document.getElementById('statTime').textContent = response.generation_time + 's';
}
// 渲染图表
function renderCharts(response) {
// 场景类型分布
if (Object.keys(response.typeCount).length > 0) {
const typeData = Object.entries(response.typeCount).map(([key, value]) => ({
label: key,
value: value
}));
renderBarChart('scenarioTypeChart', typeData, '场景类型分布');
} else {
document.getElementById('scenarioTypeChart').innerHTML = '<p style="text-align: center; color: var(--text-muted);">暂无数据</p>';
}
// ROI 分布
const roiData = [
{ label: '高 ROI', value: response.roiCount.high, color: '#2e7d32' },
{ label: '中 ROI', value: response.roiCount.medium, color: '#ef6c00' },
{ label: '低 ROI', value: response.roiCount.low, color: '#c62828' }
];
renderBarChart('roiChart', roiData, '预估 ROI 分布');
}
// 渲染场景列表
function renderScenarioList(scenarios) {
const container = document.getElementById('scenarioResults');
let html = '';
scenarios.forEach(scenario => {
const stars = Array(5).fill(0).map((_, i) =>
i < scenario.recommendation_index ? '<span class="star">★</span>' : '<span class="star star-empty">★</span>'
).join('');
const roiClass = scenario.estimated_roi === '高' ? 'roi-high' :
(scenario.estimated_roi === '中' ? 'roi-medium' : 'roi-low');
html += `
<div class="scenario-card">
<div class="scenario-header">
<div>
<span class="scenario-title">${scenario.name}</span>
<span class="scenario-type">${scenario.type}</span>
</div>
<span class="roi-badge ${roiClass}">ROI: ${scenario.estimated_roi}</span>
</div>
<div class="scenario-rating">
${stars}
<span class="rating-text">推荐指数: ${scenario.recommendation_index}/5</span>
</div>
<div class="scenario-desc">${scenario.desc}</div>
<div class="scenario-meta">
<div class="meta-item">
<div class="meta-label">商业价值</div>
<div class="meta-value">${scenario.business_value}</div>
</div>
<div class="meta-item">
<div class="meta-label">实施难度</div>
<div class="meta-value">${scenario.implementation_difficulty}</div>
</div>
<div class="meta-item" style="grid-column: span 2;">
<div class="meta-label">依赖数据资产</div>
<div class="tag-list">
${scenario.dependencies.map(dep => `<span class="tag">${dep}</span>`).join('')}
</div>
</div>
<div class="meta-item" style="grid-column: span 2;">
<div class="meta-label">技术要求</div>
<div class="tag-list">
${scenario.technical_requirements.map(req => `<span class="tag">${req}</span>`).join('')}
</div>
</div>
</div>
</div>
`;
});
container.innerHTML = html;
}
// 初始化
loadDataAssets('retail');
</script>
</body>
</html>