index.html 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848
  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
  6. <title>经营数据仪表板</title>
  7. <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
  8. <style>
  9. * {
  10. margin: 0;
  11. padding: 0;
  12. box-sizing: border-box;
  13. }
  14. body {
  15. font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  16. background: #f5f6fa;
  17. color: #2d3436;
  18. padding: 0;
  19. font-size: 14px;
  20. }
  21. .container {
  22. max-width: 100%;
  23. margin: 0 auto;
  24. padding: 0;
  25. }
  26. .header {
  27. background: linear-gradient(135deg, #e74c3c 0%, #c0392b 100%);
  28. color: white;
  29. padding: 16px;
  30. box-shadow: 0 2px 10px rgba(0,0,0,0.1);
  31. position: sticky;
  32. top: 0;
  33. z-index: 100;
  34. }
  35. .header h1 {
  36. font-size: 20px;
  37. font-weight: 600;
  38. margin-bottom: 12px;
  39. }
  40. .date-switcher {
  41. display: flex;
  42. gap: 8px;
  43. align-items: center;
  44. }
  45. .date-picker-input {
  46. flex: 1;
  47. padding: 8px 12px;
  48. background: white;
  49. border: none;
  50. border-radius: 6px;
  51. font-size: 14px;
  52. color: #2d3436;
  53. font-weight: 500;
  54. }
  55. .date-btn {
  56. padding: 8px 12px;
  57. background: rgba(255,255,255,0.2);
  58. border: 1px solid rgba(255,255,255,0.3);
  59. color: white;
  60. border-radius: 6px;
  61. cursor: pointer;
  62. font-size: 13px;
  63. transition: all 0.3s;
  64. white-space: nowrap;
  65. }
  66. .date-btn.active {
  67. background: white;
  68. color: #e74c3c;
  69. font-weight: 600;
  70. }
  71. .tab-container {
  72. background: white;
  73. padding: 12px;
  74. border-bottom: 1px solid #e1e8ed;
  75. display: flex;
  76. gap: 8px;
  77. }
  78. .tab-btn {
  79. flex: 1;
  80. padding: 10px;
  81. background: #f5f6fa;
  82. border: none;
  83. border-radius: 6px;
  84. cursor: pointer;
  85. font-size: 14px;
  86. font-weight: 500;
  87. color: #636e72;
  88. transition: all 0.3s;
  89. }
  90. .tab-btn.active {
  91. background: linear-gradient(135deg, #e74c3c 0%, #c0392b 100%);
  92. color: white;
  93. }
  94. .content {
  95. padding: 12px;
  96. }
  97. .section {
  98. background: white;
  99. border-radius: 12px;
  100. padding: 16px;
  101. margin-bottom: 16px;
  102. box-shadow: 0 2px 8px rgba(0,0,0,0.06);
  103. }
  104. .section-title {
  105. font-size: 16px;
  106. font-weight: 600;
  107. color: #2d3436;
  108. margin-bottom: 12px;
  109. padding-bottom: 8px;
  110. border-bottom: 2px solid #e74c3c;
  111. display: flex;
  112. align-items: center;
  113. }
  114. .section-title::before {
  115. content: '';
  116. width: 4px;
  117. height: 16px;
  118. background: #e74c3c;
  119. margin-right: 8px;
  120. border-radius: 2px;
  121. }
  122. .metrics-grid {
  123. display: grid;
  124. grid-template-columns: 1fr 1fr;
  125. gap: 12px;
  126. margin-top: 12px;
  127. }
  128. .metric-card {
  129. background: #f8f9fa;
  130. padding: 12px;
  131. border-radius: 8px;
  132. border-left: 3px solid #e74c3c;
  133. }
  134. .metric-label {
  135. font-size: 12px;
  136. color: #636e72;
  137. margin-bottom: 4px;
  138. }
  139. .metric-value {
  140. font-size: 18px;
  141. font-weight: 600;
  142. color: #2d3436;
  143. }
  144. .metric-value.positive {
  145. color: #00b894;
  146. }
  147. .metric-value.negative {
  148. color: #d63031;
  149. }
  150. .table-container {
  151. overflow-x: auto;
  152. margin-top: 12px;
  153. }
  154. .data-table {
  155. width: 100%;
  156. border-collapse: collapse;
  157. font-size: 12px;
  158. }
  159. .data-table th {
  160. background: #f8f9fa;
  161. padding: 10px 8px;
  162. text-align: left;
  163. font-weight: 600;
  164. color: #636e72;
  165. border-bottom: 2px solid #e1e8ed;
  166. white-space: nowrap;
  167. }
  168. .data-table td {
  169. padding: 10px 8px;
  170. border-bottom: 1px solid #e1e8ed;
  171. color: #2d3436;
  172. }
  173. .data-table tr:hover {
  174. background: #f8f9fa;
  175. }
  176. .badge {
  177. display: inline-block;
  178. padding: 4px 8px;
  179. border-radius: 4px;
  180. font-size: 11px;
  181. font-weight: 600;
  182. }
  183. .badge.success {
  184. background: #d4edda;
  185. color: #155724;
  186. }
  187. .badge.warning {
  188. background: #fff3cd;
  189. color: #856404;
  190. }
  191. .badge.danger {
  192. background: #f8d7da;
  193. color: #721c24;
  194. }
  195. .subsection {
  196. margin-top: 16px;
  197. padding-top: 16px;
  198. border-top: 1px dashed #dfe6e9;
  199. }
  200. .subsection-title {
  201. font-size: 14px;
  202. font-weight: 600;
  203. color: #636e72;
  204. margin-bottom: 8px;
  205. }
  206. @media (max-width: 480px) {
  207. .metrics-grid {
  208. grid-template-columns: 1fr;
  209. }
  210. .data-table {
  211. font-size: 11px;
  212. }
  213. .data-table th,
  214. .data-table td {
  215. padding: 8px 4px;
  216. }
  217. }
  218. /* 模态框样式 */
  219. .modal {
  220. display: none;
  221. position: fixed;
  222. z-index: 1000;
  223. left: 0;
  224. top: 0;
  225. width: 100%;
  226. height: 100%;
  227. background-color: rgba(0,0,0,0.5);
  228. animation: fadeIn 0.3s;
  229. }
  230. @keyframes fadeIn {
  231. from { opacity: 0; }
  232. to { opacity: 1; }
  233. }
  234. .modal-content {
  235. background-color: white;
  236. margin: 10% auto;
  237. padding: 20px;
  238. border-radius: 12px;
  239. width: 90%;
  240. max-width: 500px;
  241. position: relative;
  242. animation: slideIn 0.3s;
  243. }
  244. @keyframes slideIn {
  245. from {
  246. transform: translateY(-50px);
  247. opacity: 0;
  248. }
  249. to {
  250. transform: translateY(0);
  251. opacity: 1;
  252. }
  253. }
  254. .modal-header {
  255. font-size: 18px;
  256. font-weight: 600;
  257. color: #2d3436;
  258. margin-bottom: 16px;
  259. padding-bottom: 12px;
  260. border-bottom: 2px solid #e74c3c;
  261. }
  262. .close {
  263. color: #636e72;
  264. float: right;
  265. font-size: 28px;
  266. font-weight: bold;
  267. line-height: 20px;
  268. cursor: pointer;
  269. transition: color 0.3s;
  270. }
  271. .close:hover {
  272. color: #e74c3c;
  273. }
  274. .chart-container {
  275. position: relative;
  276. height: 250px;
  277. margin-top: 16px;
  278. }
  279. .clickable {
  280. cursor: pointer;
  281. transition: all 0.3s;
  282. }
  283. .clickable:hover {
  284. background: #fff5f5;
  285. transform: scale(1.02);
  286. }
  287. </style>
  288. </head>
  289. <body>
  290. <div class="container">
  291. <div class="header">
  292. <h1>📊 经营数据仪表板</h1>
  293. <div class="date-switcher">
  294. <input type="date" class="date-picker-input" id="datePicker" value="">
  295. <button class="date-btn active" onclick="switchDate('day')">当日</button>
  296. <button class="date-btn" onclick="switchDate('month')">本月</button>
  297. <button class="date-btn" onclick="switchDate('year')">当年</button>
  298. </div>
  299. </div>
  300. <div class="tab-container">
  301. <button class="tab-btn active" onclick="switchTab('overview')">总体数据</button>
  302. <button class="tab-btn" onclick="switchTab('operations')">运营指标</button>
  303. </div>
  304. <div class="content">
  305. <!-- 公司总体经营数据 -->
  306. <div id="overview-content" class="tab-content">
  307. <!-- 存量业务 -->
  308. <div class="section">
  309. <div class="section-title">存量业务</div>
  310. <div class="metrics-grid">
  311. <div class="metric-card">
  312. <div class="metric-label">资产估值</div>
  313. <div class="metric-value">¥8,520万</div>
  314. </div>
  315. <div class="metric-card">
  316. <div class="metric-label">年收入目标</div>
  317. <div class="metric-value">¥2,400万</div>
  318. </div>
  319. <div class="metric-card">
  320. <div class="metric-label">预估成本</div>
  321. <div class="metric-value">¥1,680万</div>
  322. </div>
  323. <div class="metric-card">
  324. <div class="metric-label">预估净利润</div>
  325. <div class="metric-value positive">¥720万</div>
  326. </div>
  327. </div>
  328. <div class="subsection">
  329. <div class="subsection-title">实际数据</div>
  330. <div class="metrics-grid">
  331. <div class="metric-card">
  332. <div class="metric-label">实际收入</div>
  333. <div class="metric-value">¥186.5万</div>
  334. </div>
  335. <div class="metric-card">
  336. <div class="metric-label">实际成本</div>
  337. <div class="metric-value">¥128.3万</div>
  338. </div>
  339. <div class="metric-card">
  340. <div class="metric-label">实际利润</div>
  341. <div class="metric-value positive">¥58.2万</div>
  342. </div>
  343. </div>
  344. </div>
  345. </div>
  346. <!-- 增量业务 -->
  347. <div class="section">
  348. <div class="section-title">增量业务</div>
  349. <div class="metrics-grid">
  350. <div class="metric-card">
  351. <div class="metric-label">收入</div>
  352. <div class="metric-value">¥45.8万</div>
  353. </div>
  354. <div class="metric-card">
  355. <div class="metric-label">运营成本</div>
  356. <div class="metric-value">¥18.6万</div>
  357. </div>
  358. <div class="metric-card">
  359. <div class="metric-label">投放成本</div>
  360. <div class="metric-value">¥15.2万</div>
  361. </div>
  362. <div class="metric-card">
  363. <div class="metric-label">当下利润</div>
  364. <div class="metric-value positive">¥12.0万</div>
  365. </div>
  366. </div>
  367. </div>
  368. <!-- 公司财务现金流 -->
  369. <div class="section">
  370. <div class="section-title">公司财务现金流</div>
  371. <div class="metrics-grid">
  372. <div class="metric-card">
  373. <div class="metric-label">收款</div>
  374. <div class="metric-value positive">¥232.3万</div>
  375. </div>
  376. <div class="metric-card">
  377. <div class="metric-label">支出</div>
  378. <div class="metric-value negative">¥162.1万</div>
  379. </div>
  380. <div class="metric-card" style="grid-column: 1 / -1;">
  381. <div class="metric-label">账户现金流</div>
  382. <div class="metric-value positive">¥70.2万</div>
  383. </div>
  384. </div>
  385. </div>
  386. </div>
  387. <!-- 运营指标 -->
  388. <div id="operations-content" class="tab-content" style="display: none;">
  389. <!-- 存量 -->
  390. <div class="section">
  391. <div class="section-title">存量业务</div>
  392. <div class="subsection-title">运营指标</div>
  393. <div class="table-container">
  394. <table class="data-table">
  395. <thead>
  396. <tr>
  397. <th>项目</th>
  398. <th>收入</th>
  399. <th>总粉丝</th>
  400. <th>留存粉丝</th>
  401. <th>当日掉粉</th>
  402. <th>日活率</th>
  403. <th>月活率</th>
  404. <th>ARPU值</th>
  405. </tr>
  406. </thead>
  407. <tbody>
  408. <tr>
  409. <td>短剧存量</td>
  410. <td>¥68.5万</td>
  411. <td>125,680</td>
  412. <td>118,520</td>
  413. <td>-356</td>
  414. <td><span class="badge success">32.5%</span></td>
  415. <td><span class="badge success">68.2%</span></td>
  416. <td>¥5.78</td>
  417. </tr>
  418. <tr>
  419. <td>小说存量</td>
  420. <td>¥52.3万</td>
  421. <td>98,520</td>
  422. <td>95,280</td>
  423. <td>-258</td>
  424. <td><span class="badge success">28.6%</span></td>
  425. <td><span class="badge success">65.8%</span></td>
  426. <td>¥5.31</td>
  427. </tr>
  428. <tr>
  429. <td>无双存量</td>
  430. <td>¥65.7万</td>
  431. <td>158,620</td>
  432. <td>152,360</td>
  433. <td>-412</td>
  434. <td><span class="badge warning">25.3%</span></td>
  435. <td><span class="badge success">62.5%</span></td>
  436. <td>¥4.31</td>
  437. </tr>
  438. </tbody>
  439. </table>
  440. </div>
  441. <div class="subsection">
  442. <div class="subsection-title">封禁情况</div>
  443. <div class="metrics-grid">
  444. <div class="metric-card">
  445. <div class="metric-label">总客服数</div>
  446. <div class="metric-value">186</div>
  447. </div>
  448. <div class="metric-card">
  449. <div class="metric-label">当日新增封禁</div>
  450. <div class="metric-value negative">8</div>
  451. </div>
  452. <div class="metric-card clickable" style="grid-column: 1 / -1;" onclick="showBanChart('stock')">
  453. <div class="metric-label">在封客服数量 <span style="font-size: 11px; color: #e74c3c;">▼ 点击查看7日趋势</span></div>
  454. <div class="metric-value">23</div>
  455. </div>
  456. </div>
  457. </div>
  458. </div>
  459. <!-- 增量 -->
  460. <div class="section">
  461. <div class="section-title">增量业务</div>
  462. <div class="subsection-title">投放指标</div>
  463. <div class="metrics-grid">
  464. <div class="metric-card">
  465. <div class="metric-label">投放消耗</div>
  466. <div class="metric-value">¥15.2万</div>
  467. </div>
  468. <div class="metric-card">
  469. <div class="metric-label">新增粉丝数</div>
  470. <div class="metric-value positive">12,580</div>
  471. </div>
  472. <div class="metric-card">
  473. <div class="metric-label">新增粉价</div>
  474. <div class="metric-value">¥12.08</div>
  475. </div>
  476. <div class="metric-card">
  477. <div class="metric-label">当日留存率</div>
  478. <div class="metric-value positive">82.5%</div>
  479. </div>
  480. <div class="metric-card" style="grid-column: 1 / -1;">
  481. <div class="metric-label">首日ROI</div>
  482. <div class="metric-value positive">1.35</div>
  483. </div>
  484. </div>
  485. <div class="subsection">
  486. <div class="subsection-title">运营指标</div>
  487. <div style="display: flex; gap: 8px; margin-bottom: 12px;">
  488. <button class="date-btn active" onclick="switchUserType('new')" style="flex: 1; background: rgba(231, 76, 60, 0.2); border: 1px solid rgba(231, 76, 60, 0.3); color: #e74c3c;">新用户(45天内)</button>
  489. <button class="date-btn" onclick="switchUserType('old')" style="flex: 1; background: rgba(231, 76, 60, 0.2); border: 1px solid rgba(231, 76, 60, 0.3); color: #e74c3c;">老用户(45天以上)</button>
  490. </div>
  491. <div class="table-container" id="newUserTable">
  492. <table class="data-table">
  493. <thead>
  494. <tr>
  495. <th>项目</th>
  496. <th>收入</th>
  497. <th>总粉丝</th>
  498. <th>留存粉丝</th>
  499. <th>掉粉率</th>
  500. <th>日活率</th>
  501. <th>月活率</th>
  502. <th>ARPU值</th>
  503. </tr>
  504. </thead>
  505. <tbody>
  506. <tr>
  507. <td>新无双增量</td>
  508. <td>¥28.6万</td>
  509. <td>52,360</td>
  510. <td>48,520</td>
  511. <td><span class="badge warning">7.3%</span></td>
  512. <td><span class="badge success">42.8%</span></td>
  513. <td><span class="badge success">76.5%</span></td>
  514. <td>¥5.89</td>
  515. </tr>
  516. <tr>
  517. <td>新无双存量</td>
  518. <td>¥17.2万</td>
  519. <td>28,650</td>
  520. <td>26,380</td>
  521. <td><span class="badge success">3.2%</span></td>
  522. <td><span class="badge success">38.6%</span></td>
  523. <td><span class="badge success">72.3%</span></td>
  524. <td>¥6.52</td>
  525. </tr>
  526. </tbody>
  527. </table>
  528. </div>
  529. <div class="table-container" id="oldUserTable" style="display: none;">
  530. <table class="data-table">
  531. <thead>
  532. <tr>
  533. <th>项目</th>
  534. <th>收入</th>
  535. <th>总粉丝</th>
  536. <th>留存粉丝</th>
  537. <th>掉粉率</th>
  538. <th>日活率</th>
  539. <th>月活率</th>
  540. <th>ARPU值</th>
  541. </tr>
  542. </thead>
  543. <tbody>
  544. <tr>
  545. <td>新无双增量</td>
  546. <td>¥15.8万</td>
  547. <td>38,250</td>
  548. <td>36,180</td>
  549. <td><span class="badge success">5.4%</span></td>
  550. <td><span class="badge success">35.2%</span></td>
  551. <td><span class="badge success">68.9%</span></td>
  552. <td>¥4.13</td>
  553. </tr>
  554. <tr>
  555. <td>新无双存量</td>
  556. <td>¥22.3万</td>
  557. <td>45,820</td>
  558. <td>43,650</td>
  559. <td><span class="badge success">4.7%</span></td>
  560. <td><span class="badge success">31.8%</span></td>
  561. <td><span class="badge success">65.2%</span></td>
  562. <td>¥4.87</td>
  563. </tr>
  564. </tbody>
  565. </table>
  566. </div>
  567. </div>
  568. <div class="subsection">
  569. <div class="subsection-title">封禁情况</div>
  570. <div class="metrics-grid">
  571. <div class="metric-card">
  572. <div class="metric-label">总客服数</div>
  573. <div class="metric-value">92</div>
  574. </div>
  575. <div class="metric-card">
  576. <div class="metric-label">当日新增封禁</div>
  577. <div class="metric-value negative">3</div>
  578. </div>
  579. <div class="metric-card clickable" style="grid-column: 1 / -1;" onclick="showBanChart('increment')">
  580. <div class="metric-label">在封客服数量 <span style="font-size: 11px; color: #e74c3c;">▼ 点击查看7日趋势</span></div>
  581. <div class="metric-value">11</div>
  582. </div>
  583. </div>
  584. </div>
  585. </div>
  586. </div>
  587. </div>
  588. </div>
  589. <!-- 图表模态框 -->
  590. <div id="chartModal" class="modal">
  591. <div class="modal-content">
  592. <div class="modal-header">
  593. <span class="close" onclick="closeChart()">&times;</span>
  594. <span id="chartTitle">在封客服数量 - 7日趋势</span>
  595. </div>
  596. <div class="chart-container">
  597. <canvas id="banChart"></canvas>
  598. </div>
  599. </div>
  600. </div>
  601. <script>
  602. // 初始化日期选择器为当日
  603. document.addEventListener('DOMContentLoaded', function() {
  604. const datePicker = document.getElementById('datePicker');
  605. const today = new Date().toISOString().split('T')[0];
  606. datePicker.value = today;
  607. });
  608. function switchDate(type) {
  609. const buttons = document.querySelectorAll('.date-btn');
  610. buttons.forEach(btn => btn.classList.remove('active'));
  611. event.target.classList.add('active');
  612. const datePicker = document.getElementById('datePicker');
  613. const today = new Date();
  614. // 根据类型设置日期
  615. if (type === 'day') {
  616. datePicker.value = today.toISOString().split('T')[0];
  617. } else if (type === 'month') {
  618. // 设置为本月第一天
  619. const firstDay = new Date(today.getFullYear(), today.getMonth(), 1);
  620. datePicker.value = firstDay.toISOString().split('T')[0];
  621. } else if (type === 'year') {
  622. // 设置为当年第一天
  623. const firstDay = new Date(today.getFullYear(), 0, 1);
  624. datePicker.value = firstDay.toISOString().split('T')[0];
  625. }
  626. console.log('切换到:', type, '日期:', datePicker.value);
  627. }
  628. function switchTab(tab) {
  629. const tabButtons = document.querySelectorAll('.tab-btn');
  630. tabButtons.forEach(btn => btn.classList.remove('active'));
  631. event.target.classList.add('active');
  632. // 隐藏所有内容
  633. document.getElementById('overview-content').style.display = 'none';
  634. document.getElementById('operations-content').style.display = 'none';
  635. // 显示选中的内容
  636. if (tab === 'overview') {
  637. document.getElementById('overview-content').style.display = 'block';
  638. } else if (tab === 'operations') {
  639. document.getElementById('operations-content').style.display = 'block';
  640. }
  641. }
  642. function switchUserType(type) {
  643. const buttons = event.target.parentElement.querySelectorAll('.date-btn');
  644. buttons.forEach(btn => btn.classList.remove('active'));
  645. event.target.classList.add('active');
  646. const newUserTable = document.getElementById('newUserTable');
  647. const oldUserTable = document.getElementById('oldUserTable');
  648. if (type === 'new') {
  649. newUserTable.style.display = 'block';
  650. oldUserTable.style.display = 'none';
  651. } else if (type === 'old') {
  652. newUserTable.style.display = 'none';
  653. oldUserTable.style.display = 'block';
  654. }
  655. console.log('切换用户类型:', type);
  656. }
  657. // 图表相关功能
  658. let currentChart = null;
  659. function showBanChart(type) {
  660. const modal = document.getElementById('chartModal');
  661. modal.style.display = 'block';
  662. // 销毁旧图表
  663. if (currentChart) {
  664. currentChart.destroy();
  665. }
  666. // 准备数据
  667. let data, title;
  668. if (type === 'stock') {
  669. title = '存量业务 - 在封客服数量 7日趋势';
  670. data = {
  671. labels: ['12/21', '12/22', '12/23', '12/24', '12/25', '12/26', '12/27'],
  672. datasets: [{
  673. label: '在封客服数',
  674. data: [18, 20, 22, 25, 21, 23, 23],
  675. borderColor: '#e74c3c',
  676. backgroundColor: 'rgba(231, 76, 60, 0.1)',
  677. tension: 0.4,
  678. fill: true,
  679. pointRadius: 5,
  680. pointHoverRadius: 7,
  681. pointBackgroundColor: '#e74c3c',
  682. pointBorderColor: '#fff',
  683. pointBorderWidth: 2
  684. }]
  685. };
  686. } else {
  687. title = '增量业务 - 在封客服数量 7日趋势';
  688. data = {
  689. labels: ['12/21', '12/22', '12/23', '12/24', '12/25', '12/26', '12/27'],
  690. datasets: [{
  691. label: '在封客服数',
  692. data: [8, 9, 10, 12, 11, 10, 11],
  693. borderColor: '#e74c3c',
  694. backgroundColor: 'rgba(231, 76, 60, 0.1)',
  695. tension: 0.4,
  696. fill: true,
  697. pointRadius: 5,
  698. pointHoverRadius: 7,
  699. pointBackgroundColor: '#e74c3c',
  700. pointBorderColor: '#fff',
  701. pointBorderWidth: 2
  702. }]
  703. };
  704. }
  705. document.getElementById('chartTitle').textContent = title;
  706. // 创建图表
  707. const ctx = document.getElementById('banChart').getContext('2d');
  708. currentChart = new Chart(ctx, {
  709. type: 'line',
  710. data: data,
  711. options: {
  712. responsive: true,
  713. maintainAspectRatio: false,
  714. plugins: {
  715. legend: {
  716. display: false
  717. },
  718. tooltip: {
  719. backgroundColor: 'rgba(0, 0, 0, 0.8)',
  720. padding: 12,
  721. titleColor: '#fff',
  722. bodyColor: '#fff',
  723. borderColor: '#e74c3c',
  724. borderWidth: 1
  725. }
  726. },
  727. scales: {
  728. y: {
  729. beginAtZero: true,
  730. ticks: {
  731. precision: 0,
  732. font: {
  733. size: 12
  734. }
  735. },
  736. grid: {
  737. color: 'rgba(0, 0, 0, 0.05)'
  738. }
  739. },
  740. x: {
  741. ticks: {
  742. font: {
  743. size: 11
  744. }
  745. },
  746. grid: {
  747. display: false
  748. }
  749. }
  750. }
  751. }
  752. });
  753. }
  754. function closeChart() {
  755. const modal = document.getElementById('chartModal');
  756. modal.style.display = 'none';
  757. if (currentChart) {
  758. currentChart.destroy();
  759. currentChart = null;
  760. }
  761. }
  762. // 点击模态框外部关闭
  763. window.onclick = function(event) {
  764. const modal = document.getElementById('chartModal');
  765. if (event.target == modal) {
  766. closeChart();
  767. }
  768. }
  769. </script>
  770. </body>
  771. </html>