idea_house.html 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563
  1. <!DOCTYPE html>
  2. <html lang="zh">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>Idea House - Data Field Analysis</title>
  7. <link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
  8. <style>
  9. .idea-house-container {
  10. max-width: 1200px;
  11. margin: 0 auto;
  12. padding: 20px;
  13. }
  14. .data-fields-section {
  15. background: rgba(255, 255, 255, 0.9);
  16. border-radius: 8px;
  17. padding: 20px;
  18. margin-bottom: 20px;
  19. box-shadow: 0 2px 4px rgba(0,0,0,0.1);
  20. }
  21. .api-config-section {
  22. background: rgba(240, 242, 255, 0.9);
  23. border-radius: 8px;
  24. padding: 20px;
  25. margin-bottom: 20px;
  26. box-shadow: 0 2px 4px rgba(0,0,0,0.1);
  27. border: 1px solid rgba(102, 126, 234, 0.2);
  28. }
  29. .data-fields-table {
  30. width: 100%;
  31. border-collapse: collapse;
  32. margin-top: 20px;
  33. }
  34. .data-fields-table th,
  35. .data-fields-table td {
  36. padding: 12px;
  37. text-align: left;
  38. border-bottom: 1px solid #ddd;
  39. }
  40. .data-fields-table th {
  41. background-color: #f5f5f5;
  42. font-weight: bold;
  43. position: sticky;
  44. top: 0;
  45. z-index: 10;
  46. }
  47. .data-fields-table tr:hover {
  48. background-color: #f0f0f0;
  49. cursor: pointer;
  50. }
  51. .data-fields-table tr.selected {
  52. background-color: #e3f2fd;
  53. }
  54. .field-checkbox {
  55. width: 20px;
  56. height: 20px;
  57. cursor: pointer;
  58. }
  59. .selected-fields-section {
  60. background: rgba(255, 255, 255, 0.9);
  61. border-radius: 8px;
  62. padding: 20px;
  63. margin-bottom: 20px;
  64. box-shadow: 0 2px 4px rgba(0,0,0,0.1);
  65. }
  66. .selected-field-item {
  67. display: inline-block;
  68. background: #e3f2fd;
  69. padding: 5px 10px;
  70. margin: 5px;
  71. border-radius: 4px;
  72. font-size: 14px;
  73. }
  74. .results-section {
  75. background: rgba(255, 255, 255, 0.9);
  76. border-radius: 8px;
  77. padding: 20px;
  78. box-shadow: 0 2px 4px rgba(0,0,0,0.1);
  79. }
  80. .markdown-content {
  81. padding: 20px;
  82. background: #f9f9f9;
  83. border-radius: 4px;
  84. font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;
  85. line-height: 1.6;
  86. overflow-x: auto;
  87. }
  88. .markdown-content h1 {
  89. color: #333;
  90. border-bottom: 2px solid #4caf50;
  91. padding-bottom: 10px;
  92. margin-bottom: 20px;
  93. }
  94. .markdown-content h2 {
  95. color: #555;
  96. margin-top: 25px;
  97. margin-bottom: 15px;
  98. }
  99. .markdown-content h3 {
  100. color: #666;
  101. margin-top: 20px;
  102. margin-bottom: 10px;
  103. }
  104. .markdown-content ul {
  105. margin: 10px 0;
  106. padding-left: 20px;
  107. }
  108. .markdown-content li {
  109. margin: 5px 0;
  110. }
  111. .markdown-content pre {
  112. background: #f0f0f0;
  113. padding: 15px;
  114. border-radius: 4px;
  115. overflow-x: auto;
  116. font-family: 'Courier New', monospace;
  117. }
  118. .markdown-content code {
  119. background: #f0f0f0;
  120. padding: 2px 6px;
  121. border-radius: 3px;
  122. font-family: 'Courier New', monospace;
  123. }
  124. .markdown-content strong {
  125. color: #333;
  126. font-weight: bold;
  127. }
  128. .loading-overlay {
  129. position: fixed;
  130. top: 0;
  131. left: 0;
  132. width: 100%;
  133. height: 100%;
  134. background: rgba(0, 0, 0, 0.5);
  135. display: none;
  136. justify-content: center;
  137. align-items: center;
  138. z-index: 1000;
  139. }
  140. .loading-content {
  141. background: white;
  142. padding: 30px;
  143. border-radius: 8px;
  144. text-align: center;
  145. }
  146. .params-section {
  147. margin: 20px 0;
  148. padding: 15px;
  149. background: #f5f5f5;
  150. border-radius: 4px;
  151. }
  152. .params-row {
  153. display: flex;
  154. gap: 15px;
  155. margin-bottom: 15px;
  156. flex-wrap: wrap;
  157. }
  158. .param-group {
  159. flex: 1;
  160. min-width: 200px;
  161. }
  162. .param-group label {
  163. display: block;
  164. margin-bottom: 5px;
  165. font-weight: bold;
  166. }
  167. .stats-info {
  168. margin: 10px 0;
  169. color: #666;
  170. }
  171. .table-container {
  172. max-height: 500px;
  173. overflow-y: auto;
  174. border: 1px solid #ddd;
  175. border-radius: 4px;
  176. }
  177. .toggle-btn {
  178. background: #f0f0f0;
  179. border: 1px solid #ddd;
  180. color: #333;
  181. cursor: pointer;
  182. transition: all 0.3s ease;
  183. }
  184. .toggle-btn:hover {
  185. background: #e0e0e0;
  186. border-color: #999;
  187. }
  188. /* 数据字段过滤样式 */
  189. .data-fields-controls {
  190. display: flex;
  191. align-items: center;
  192. gap: 20px;
  193. padding: 15px;
  194. background: #f8f9fa;
  195. border-bottom: 1px solid #dee2e6;
  196. border-radius: 4px 4px 0 0;
  197. flex-wrap: wrap;
  198. }
  199. .filter-label {
  200. font-weight: 600;
  201. color: #495057;
  202. }
  203. .filter-options {
  204. display: flex;
  205. gap: 15px;
  206. flex-wrap: wrap;
  207. }
  208. .filter-options label {
  209. display: flex;
  210. align-items: center;
  211. gap: 5px;
  212. cursor: pointer;
  213. font-size: 14px;
  214. }
  215. .filter-actions {
  216. display: flex;
  217. gap: 10px;
  218. margin-left: auto;
  219. }
  220. .data-fields-stats {
  221. padding: 10px 15px;
  222. background: #f8f9fa;
  223. border-bottom: 1px solid #dee2e6;
  224. font-size: 14px;
  225. color: #6c757d;
  226. }
  227. .data-fields-table {
  228. width: 100%;
  229. border-collapse: collapse;
  230. font-size: 14px;
  231. }
  232. .data-fields-table th,
  233. .data-fields-table td {
  234. padding: 8px 12px;
  235. text-align: left;
  236. border-bottom: 1px solid #dee2e6;
  237. }
  238. .data-fields-table th {
  239. background: #f8f9fa;
  240. font-weight: 600;
  241. color: #495057;
  242. position: sticky;
  243. top: 0;
  244. z-index: 10;
  245. }
  246. .header-row th {
  247. position: relative;
  248. }
  249. .sort-btn {
  250. background: none;
  251. border: none;
  252. cursor: pointer;
  253. margin-left: 5px;
  254. padding: 2px 4px;
  255. font-size: 12px;
  256. color: #6c757d;
  257. border-radius: 2px;
  258. }
  259. .sort-btn:hover {
  260. background: #dee2e6;
  261. color: #495057;
  262. }
  263. .sort-btn.asc {
  264. color: #28a745;
  265. }
  266. .sort-btn.desc {
  267. color: #dc3545;
  268. }
  269. .filter-row th {
  270. padding: 5px 8px;
  271. background: #ffffff;
  272. }
  273. .column-filter,
  274. .column-filter-min,
  275. .column-filter-max {
  276. width: 100%;
  277. padding: 4px 6px;
  278. border: 1px solid #ced4da;
  279. border-radius: 3px;
  280. font-size: 12px;
  281. }
  282. .column-filter.active,
  283. .column-filter-min.active,
  284. .column-filter-max.active {
  285. border-color: #4caf50;
  286. background-color: #f0f8f0;
  287. }
  288. .range-filter {
  289. display: flex;
  290. align-items: center;
  291. gap: 3px;
  292. }
  293. .range-filter input {
  294. flex: 1;
  295. min-width: 0;
  296. }
  297. .range-filter span {
  298. font-size: 12px;
  299. color: #6c757d;
  300. }
  301. .data-fields-table tbody tr {
  302. cursor: pointer;
  303. transition: background-color 0.2s;
  304. }
  305. .data-fields-table tbody tr:hover {
  306. background-color: #f8f9fa;
  307. }
  308. .data-fields-table tbody tr.selected {
  309. background-color: #e8f5e8;
  310. border-left: 3px solid #4caf50;
  311. }
  312. .field-checkbox {
  313. cursor: pointer;
  314. }
  315. .btn-small {
  316. padding: 5px 10px;
  317. font-size: 12px;
  318. border-radius: 3px;
  319. }
  320. </style>
  321. </head>
  322. <body>
  323. <div class="container">
  324. <header>
  325. <h1>创意之家</h1>
  326. <p class="subtitle">让数据大声发言</p>
  327. <a href="/" class="btn btn-outline">← 返回主页</a>
  328. </header>
  329. <div class="idea-house-container">
  330. <!-- Coze API 配置部分 -->
  331. <div class="api-config-section">
  332. <h2>Coze API 配置</h2>
  333. <div class="params-section">
  334. <div class="params-row">
  335. <div class="param-group" style="flex: 2;">
  336. <label for="cozeApiTokenInput">
  337. Coze API 令牌:
  338. <button type="button" id="toggleApiTokenBtn" class="toggle-btn" style="margin-left: 10px; padding: 2px 8px; font-size: 12px;">显示</button>
  339. </label>
  340. <input type="password" id="cozeApiTokenInput" class="form-input" placeholder="输入您的 Coze API 令牌" value="pat_OCxUpnmL7hCvUxEWwcKL5XwUOdoiA3eWLzwY6L8W9sQVN1saJnoMrDNyhFhEn63l">
  341. </div>
  342. <div class="param-group">
  343. <label for="workflowIdInput">工作流 ID:</label>
  344. <input type="text" id="workflowIdInput" class="form-input" placeholder="输入工作流 ID" value="7522912027267956786">
  345. </div>
  346. </div>
  347. <div class="info-message" style="margin-top: 10px; font-size: 14px; color: #666;">
  348. <em>提供默认值。您可以用自己的 Coze API 凭证替换它们。</em>
  349. </div>
  350. <div style="margin-top: 15px;">
  351. <button id="saveCozeConfigBtn" class="btn btn-secondary btn-small">保存配置</button>
  352. <button id="clearCozeConfigBtn" class="btn btn-outline btn-small" style="margin-left: 10px;">重置为默认</button>
  353. <span id="saveConfigMessage" style="margin-left: 10px; color: #4caf50; display: none;">配置已保存!</span>
  354. </div>
  355. </div>
  356. </div>
  357. <!-- 数据字段加载部分 -->
  358. <div class="data-fields-section">
  359. <h2>从 BRAIN 加载数据字段</h2>
  360. <div class="params-section">
  361. <div class="params-row">
  362. <div class="param-group">
  363. <label for="regionInput">区域:</label>
  364. <input type="text" id="regionInput" class="form-input" value="美国">
  365. </div>
  366. <div class="param-group">
  367. <label for="delayInput">延迟:</label>
  368. <input type="number" id="delayInput" class="form-input" value="1">
  369. </div>
  370. <div class="param-group">
  371. <label for="universeInput">宇宙:</label>
  372. <input type="text" id="universeInput" class="form-input" value="前3000">
  373. </div>
  374. <div class="param-group">
  375. <label for="datasetInput">数据集 ID:</label>
  376. <input type="text" id="datasetInput" class="form-input" value="analyst10">
  377. </div>
  378. </div>
  379. <button id="loadDataFieldsBtn" class="btn btn-primary">加载数据字段</button>
  380. </div>
  381. <div id="dataFieldsStats" class="stats-info"></div>
  382. <div class="table-container" id="tableContainer" style="display: none;">
  383. <!-- 添加过滤控件 -->
  384. <div class="data-fields-controls">
  385. <div class="filter-label">
  386. <span>快速过滤 👉</span>
  387. </div>
  388. <div class="filter-options">
  389. <label>
  390. <input type="checkbox" id="filterHighCoverage"> 高覆盖率 (>90%)
  391. </label>
  392. <label>
  393. <input type="checkbox" id="filterPopular"> 流行 (>1000 用户)
  394. </label>
  395. <label>
  396. <input type="checkbox" id="filterMatrixOnly"> 仅限矩阵类型
  397. </label>
  398. </div>
  399. <div class="filter-actions">
  400. <button id="selectAllFiltered" class="btn btn-small btn-secondary">选择所有过滤项</button>
  401. <button id="clearAllSelected" class="btn btn-small btn-outline">清除所有</button>
  402. </div>
  403. </div>
  404. <div class="data-fields-stats">
  405. <span id="dataFieldsCount">已加载 0 个字段</span> |
  406. <span id="filteredCount">已过滤 0 个</span> |
  407. <span id="selectedFieldsCount">已选择 0 个</span>
  408. </div>
  409. <table class="data-fields-table" id="dataFieldsTable">
  410. <thead>
  411. <tr class="header-row">
  412. <th style="width: 40px;">
  413. <input type="checkbox" id="selectAllCheckbox" title="选择/取消选择所有">
  414. </th>
  415. <th style="width: 200px; min-width: 150px;">
  416. 字段 ID
  417. <button class="sort-btn" data-column="id" data-order="asc">↕</button>
  418. </th>
  419. <th style="min-width: 300px;">
  420. 描述
  421. <button class="sort-btn" data-column="description" data-order="asc">↕</button>
  422. </th>
  423. <th style="width: 100px;">
  424. 类型
  425. <button class="sort-btn" data-column="type" data-order="asc">↕</button>
  426. </th>
  427. <th style="width: 150px;">
  428. 覆盖率
  429. <button class="sort-btn" data-column="coverage" data-order="asc">↕</button>
  430. </th>
  431. <th style="width: 100px;">
  432. 用户数
  433. <button class="sort-btn" data-column="userCount" data-order="asc">↕</button>
  434. </th>
  435. <th style="width: 100px;">
  436. Alphas
  437. <button class="sort-btn" data-column="alphaCount" data-order="asc">↕</button>
  438. </th>
  439. </tr>
  440. <tr class="filter-row">
  441. <th></th>
  442. <th>
  443. <input type="text" class="column-filter" data-column="id" placeholder="过滤 ID...">
  444. </th>
  445. <th>
  446. <input type="text" class="column-filter" data-column="description" placeholder="过滤描述...">
  447. </th>
  448. <th>
  449. <select class="column-filter" data-column="type" id="typeFilter">
  450. <option value="">所有类型</option>
  451. </select>
  452. </th>
  453. <th>
  454. <div class="range-filter">
  455. <input type="number" class="column-filter-min" data-column="coverage" placeholder="最小 %" min="0" max="100" step="0.1">
  456. <span>-</span>
  457. <input type="number" class="column-filter-max" data-column="coverage" placeholder="最大 %" min="0" max="100" step="0.1">
  458. </div>
  459. </th>
  460. <th>
  461. <input type="number" class="column-filter" data-column="userCount" placeholder="最小用户数" min="0">
  462. </th>
  463. <th>
  464. <input type="number" class="column-filter" data-column="alphaCount" placeholder="最小 Alphas" min="0">
  465. </th>
  466. </tr>
  467. </thead>
  468. <tbody id="dataFieldsTableBody">
  469. <!-- 表格行将在这里填充 -->
  470. </tbody>
  471. </table>
  472. </div>
  473. </div>
  474. <!-- 选择的字段部分 -->
  475. <div class="selected-fields-section" id="selectedFieldsSection" style="display: none;">
  476. <h2>选择的字段</h2>
  477. <div id="selectedFieldsList"></div>
  478. <button id="clearSelectionBtn" class="btn btn-secondary">清除选择</button>
  479. <button id="processFieldsBtn" class="btn btn-primary">处理选择的字段</button>
  480. </div>
  481. <!-- 结果部分 -->
  482. <div class="results-section" id="resultsSection" style="display: none;">
  483. <h2>分析结果</h2>
  484. <div class="markdown-content" id="resultsContent">
  485. <!-- 结果将在这里显示 -->
  486. </div>
  487. </div>
  488. </div>
  489. </div>
  490. <!-- 加载覆盖层 -->
  491. <div class="loading-overlay" id="loadingOverlay">
  492. <div class="loading-content">
  493. <h3>处理中...</h3>
  494. <p>请稍等,我们正在分析您选择的字段...</p>
  495. </div>
  496. </div>
  497. <script src="{{ url_for('static', filename='idea_house.js') }}"></script>
  498. </body>
  499. </html>