Spaces:
Running
Running
Upload 3 files
Browse files- app.py +106 -63
- templates/dashboard.html +13 -73
app.py
CHANGED
@@ -56,10 +56,19 @@ total_tokens = {
|
|
56 |
}
|
57 |
|
58 |
# 计算点信息
|
59 |
-
compute_points =
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
|
61 |
# 计算点使用日志
|
62 |
-
compute_points_log =
|
|
|
|
|
|
|
63 |
|
64 |
|
65 |
# 记录启动时间
|
@@ -812,71 +821,105 @@ def update_model_stats(model, prompt_tokens, completion_tokens):
|
|
812 |
|
813 |
# 获取计算点信息
|
814 |
def get_compute_points():
|
815 |
-
global compute_points,
|
816 |
|
817 |
-
|
818 |
-
|
819 |
|
820 |
-
|
821 |
-
|
822 |
-
|
823 |
-
|
824 |
-
|
825 |
-
|
826 |
-
|
827 |
-
|
828 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
829 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
830 |
|
831 |
-
|
832 |
-
|
833 |
-
|
834 |
-
|
835 |
-
|
836 |
-
|
837 |
-
|
838 |
-
|
839 |
-
|
840 |
-
|
841 |
-
|
842 |
-
|
843 |
-
|
844 |
-
|
845 |
-
|
846 |
-
|
847 |
-
|
848 |
-
|
849 |
-
|
850 |
-
|
851 |
-
|
852 |
-
|
853 |
-
|
854 |
-
|
855 |
-
|
856 |
-
|
857 |
-
|
858 |
-
|
859 |
-
|
860 |
-
|
861 |
-
|
862 |
-
|
863 |
-
|
864 |
-
|
865 |
-
|
866 |
-
|
867 |
-
|
868 |
-
|
869 |
-
|
870 |
-
|
871 |
-
user_compute_points["error"] = str(e)
|
872 |
-
user_compute_points_log["error"] = str(e)
|
873 |
-
|
874 |
-
new_compute_points.append(user_compute_points)
|
875 |
-
new_compute_points_log.append(user_compute_points_log)
|
876 |
-
|
877 |
-
# 更新全局变量
|
878 |
-
compute_points = new_compute_points
|
879 |
-
compute_points_log = new_compute_points_log
|
880 |
|
881 |
|
882 |
# 添加登录相关路由
|
|
|
56 |
}
|
57 |
|
58 |
# 计算点信息
|
59 |
+
compute_points = {
|
60 |
+
"left": 0, # 剩余计算点
|
61 |
+
"total": 0, # 总计算点
|
62 |
+
"used": 0, # 已使用计算点
|
63 |
+
"percentage": 0, # 使用百分比
|
64 |
+
"last_update": None # 最后更新时间
|
65 |
+
}
|
66 |
|
67 |
# 计算点使用日志
|
68 |
+
compute_points_log = {
|
69 |
+
"columns": {}, # 列名
|
70 |
+
"log": [] # 日志数据
|
71 |
+
}
|
72 |
|
73 |
|
74 |
# 记录启动时间
|
|
|
821 |
|
822 |
# 获取计算点信息
|
823 |
def get_compute_points():
|
824 |
+
global compute_points, USER_DATA
|
825 |
|
826 |
+
if USER_NUM == 0:
|
827 |
+
return
|
828 |
|
829 |
+
try:
|
830 |
+
# 使用第一个用户的会话和凭据
|
831 |
+
session, cookies, session_token, _, _ = USER_DATA[0]
|
832 |
+
|
833 |
+
# 检查token是否有效
|
834 |
+
if is_token_expired(session_token):
|
835 |
+
session_token = refresh_token(session, cookies)
|
836 |
+
if not session_token:
|
837 |
+
print("刷新token失败,无法获取计算点信息")
|
838 |
+
return
|
839 |
+
USER_DATA[0] = (session, cookies, session_token, USER_DATA[0][3], USER_DATA[0][4])
|
840 |
+
|
841 |
+
headers = {
|
842 |
+
"accept": "application/json, text/plain, */*",
|
843 |
+
"accept-language": "zh-CN,zh;q=0.9",
|
844 |
+
"baggage": f"sentry-environment=production,sentry-release=93da8385541a6ce339b1f41b0c94428c70657e22,sentry-public_key=3476ea6df1585dd10e92cdae3a66ff49,sentry-trace_id={TRACE_ID}",
|
845 |
+
"reai-ui": "1",
|
846 |
+
"sec-ch-ua": "\"Chromium\";v=\"116\", \"Not)A;Brand\";v=\"24\", \"Google Chrome\";v=\"116\"",
|
847 |
+
"sec-ch-ua-mobile": "?0",
|
848 |
+
"sec-ch-ua-platform": "\"Windows\"",
|
849 |
+
"sec-fetch-dest": "empty",
|
850 |
+
"sec-fetch-mode": "cors",
|
851 |
+
"sec-fetch-site": "same-origin",
|
852 |
+
"sentry-trace": SENTRY_TRACE,
|
853 |
+
"session-token": session_token,
|
854 |
+
"x-abacus-org-host": "apps",
|
855 |
+
"cookie": cookies
|
856 |
}
|
857 |
+
|
858 |
+
response = session.get(
|
859 |
+
COMPUTE_POINTS_URL,
|
860 |
+
headers=headers
|
861 |
+
)
|
862 |
+
|
863 |
+
if response.status_code == 200:
|
864 |
+
result = response.json()
|
865 |
+
if result.get("success") and "result" in result:
|
866 |
+
data = result["result"]
|
867 |
+
compute_points["left"] = data.get("computePointsLeft", 0)
|
868 |
+
compute_points["total"] = data.get("totalComputePoints", 0)
|
869 |
+
compute_points["used"] = compute_points["total"] - compute_points["left"]
|
870 |
+
compute_points["percentage"] = round((compute_points["used"] / compute_points["total"]) * 100, 2) if compute_points["total"] > 0 else 0
|
871 |
+
compute_points["last_update"] = datetime.now()
|
872 |
+
print(f"计算点信息更新成功: 剩余 {compute_points['left']}, 总计 {compute_points['total']}")
|
873 |
+
|
874 |
+
# 获取计算点使用日志
|
875 |
+
get_compute_points_log(session, cookies, session_token)
|
876 |
+
else:
|
877 |
+
print(f"获取计算点信息失败: {result.get('error', '未知错误')}")
|
878 |
+
else:
|
879 |
+
print(f"获取计算点信息失败,状态码: {response.status_code}")
|
880 |
+
except Exception as e:
|
881 |
+
print(f"获取计算点信息异常: {e}")
|
882 |
|
883 |
+
# 获取计算点使用日志
|
884 |
+
def get_compute_points_log(session, cookies, session_token):
|
885 |
+
global compute_points_log
|
886 |
+
|
887 |
+
try:
|
888 |
+
headers = {
|
889 |
+
"accept": "application/json, text/plain, */*",
|
890 |
+
"accept-language": "zh-CN,zh;q=0.9",
|
891 |
+
"content-type": "application/json",
|
892 |
+
"reai-ui": "1",
|
893 |
+
"sec-ch-ua": "\"Chromium\";v=\"116\", \"Not)A;Brand\";v=\"24\", \"Google Chrome\";v=\"116\"",
|
894 |
+
"sec-ch-ua-mobile": "?0",
|
895 |
+
"sec-ch-ua-platform": "\"Windows\"",
|
896 |
+
"sec-fetch-dest": "empty",
|
897 |
+
"sec-fetch-mode": "cors",
|
898 |
+
"sec-fetch-site": "same-site",
|
899 |
+
"session-token": session_token,
|
900 |
+
"x-abacus-org-host": "apps",
|
901 |
+
"cookie": cookies
|
902 |
+
}
|
903 |
+
|
904 |
+
response = session.post(
|
905 |
+
COMPUTE_POINTS_LOG_URL,
|
906 |
+
headers=headers,
|
907 |
+
json={"byLlm": True}
|
908 |
+
)
|
909 |
+
|
910 |
+
if response.status_code == 200:
|
911 |
+
result = response.json()
|
912 |
+
if result.get("success") and "result" in result:
|
913 |
+
data = result["result"]
|
914 |
+
compute_points_log["columns"] = data.get("columns", {})
|
915 |
+
compute_points_log["log"] = data.get("log", [])
|
916 |
+
print(f"计算点使用日志更新成功,获取到 {len(compute_points_log['log'])} 条记录")
|
917 |
+
else:
|
918 |
+
print(f"获取计算点使用日志失败: {result.get('error', '未知错误')}")
|
919 |
+
else:
|
920 |
+
print(f"获取计算点使用日志失败,状态码: {response.status_code}")
|
921 |
+
except Exception as e:
|
922 |
+
print(f"获取计算点使用日志异常: {e}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
923 |
|
924 |
|
925 |
# 添加登录相关路由
|
templates/dashboard.html
CHANGED
@@ -550,68 +550,43 @@
|
|
550 |
</div>
|
551 |
|
552 |
<div class="grid">
|
553 |
-
{% if compute_points %}
|
554 |
-
{% for user_points in compute_points %}
|
555 |
<div class="card">
|
556 |
<div class="card-header">
|
557 |
<h2 class="card-title">
|
558 |
<span class="card-icon">💰</span>
|
559 |
-
|
560 |
</h2>
|
561 |
</div>
|
562 |
-
{% if user_points.error %}
|
563 |
-
<div class="status-item">
|
564 |
-
<span class="status-label">错误</span>
|
565 |
-
<span class="status-value danger">获取失败: {{ user_points.error }}</span>
|
566 |
-
</div>
|
567 |
-
{% else %}
|
568 |
<div class="status-item">
|
569 |
<span class="status-label">总计算点</span>
|
570 |
-
<span class="status-value compute-points">{{
|
571 |
</div>
|
572 |
<div class="status-item">
|
573 |
<span class="status-label">已使用</span>
|
574 |
-
<span class="status-value compute-points">{{
|
575 |
</div>
|
576 |
<div class="status-item">
|
577 |
<span class="status-label">剩余</span>
|
578 |
-
<span class="status-value compute-points">{{
|
579 |
</div>
|
580 |
<div class="status-item">
|
581 |
<span class="status-label">使用比例</span>
|
582 |
<div style="width: 100%; text-align: right;">
|
583 |
-
<span class="status-value compute-points {% if
|
584 |
-
{{
|
585 |
</span>
|
586 |
<div class="progress-container">
|
587 |
-
<div class="progress-bar {% if
|
588 |
-
data-percentage="{{ user_points.percentage }}"></div>
|
589 |
</div>
|
590 |
</div>
|
591 |
</div>
|
592 |
-
{% if
|
593 |
<div class="status-item">
|
594 |
<span class="status-label">最后更新时间</span>
|
595 |
-
<span class="status-value">{{
|
596 |
</div>
|
597 |
{% endif %}
|
598 |
-
{% endif %} {# End if user_points.error #}
|
599 |
-
</div>
|
600 |
-
{% endfor %}
|
601 |
-
{% else %}
|
602 |
-
<div class="card">
|
603 |
-
<div class="card-header">
|
604 |
-
<h2 class="card-title">
|
605 |
-
<span class="card-icon">💰</span>
|
606 |
-
计算点信息
|
607 |
-
</h2>
|
608 |
-
</div>
|
609 |
-
<div class="status-item">
|
610 |
-
<span class="status-label">状态</span>
|
611 |
-
<span class="status-value warning">暂无计算点数据或未配置用户</span>
|
612 |
-
</div>
|
613 |
</div>
|
614 |
-
{% endif %} {# End if compute_points #}
|
615 |
|
616 |
<div class="card">
|
617 |
<div class="card-header">
|
@@ -660,34 +635,26 @@
|
|
660 |
</div>
|
661 |
</div>
|
662 |
|
663 |
-
{% if compute_points_log %}
|
664 |
-
{% for user_log in compute_points_log %}
|
665 |
<div class="card">
|
666 |
<div class="card-header">
|
667 |
<h2 class="card-title">
|
668 |
<span class="card-icon">📊</span>
|
669 |
-
|
670 |
</h2>
|
671 |
</div>
|
672 |
-
{% if user_log.error %}
|
673 |
-
<div class="status-item">
|
674 |
-
<span class="status-label">错误</span>
|
675 |
-
<span class="status-value danger">获取日志失败: {{ user_log.error }}</span>
|
676 |
-
</div>
|
677 |
-
{% elif user_log.log %}
|
678 |
<div class="table-container">
|
679 |
<table class="data-table">
|
680 |
<thead>
|
681 |
<tr>
|
682 |
-
{% for key, value in
|
683 |
<th>{{ value }}</th>
|
684 |
{% endfor %}
|
685 |
</tr>
|
686 |
</thead>
|
687 |
<tbody>
|
688 |
-
{% for entry in
|
689 |
<tr>
|
690 |
-
{% for key, value in
|
691 |
<td class="compute-points">{{ entry.get(key, 0) }}</td>
|
692 |
{% endfor %}
|
693 |
</tr>
|
@@ -695,28 +662,7 @@
|
|
695 |
</tbody>
|
696 |
</table>
|
697 |
</div>
|
698 |
-
{% else %}
|
699 |
-
<div class="status-item">
|
700 |
-
<span class="status-label">状态</span>
|
701 |
-
<span class="status-value">暂无日志记录</span>
|
702 |
-
</div>
|
703 |
-
{% endif %}
|
704 |
</div>
|
705 |
-
{% endfor %}
|
706 |
-
{% else %}
|
707 |
-
<div class="card">
|
708 |
-
<div class="card-header">
|
709 |
-
<h2 class="card-title">
|
710 |
-
<span class="card-icon">📊</span>
|
711 |
-
计算点使用日志
|
712 |
-
</h2>
|
713 |
-
</div>
|
714 |
-
<div class="status-item">
|
715 |
-
<span class="status-label">状态</span>
|
716 |
-
<span class="status-value warning">暂无日志数据或未配置用户</span>
|
717 |
-
</div>
|
718 |
-
</div>
|
719 |
-
{% endif %}
|
720 |
|
721 |
<div class="card">
|
722 |
<div class="card-header">
|
@@ -823,12 +769,6 @@
|
|
823 |
// 初始化隐藏回到顶部按钮
|
824 |
document.querySelector('.float-btn').style.opacity = '0';
|
825 |
|
826 |
-
// 设置进度条宽度
|
827 |
-
document.querySelectorAll('.progress-bar[data-percentage]').forEach(bar => {
|
828 |
-
const percentage = bar.getAttribute('data-percentage');
|
829 |
-
bar.style.width = `${percentage}%`;
|
830 |
-
});
|
831 |
-
|
832 |
// 模型统计折叠功能
|
833 |
const toggleBtn = document.getElementById('toggleModelStats');
|
834 |
const hiddenModels = document.querySelectorAll('.hidden-model');
|
|
|
550 |
</div>
|
551 |
|
552 |
<div class="grid">
|
|
|
|
|
553 |
<div class="card">
|
554 |
<div class="card-header">
|
555 |
<h2 class="card-title">
|
556 |
<span class="card-icon">💰</span>
|
557 |
+
计算点信息
|
558 |
</h2>
|
559 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
560 |
<div class="status-item">
|
561 |
<span class="status-label">总计算点</span>
|
562 |
+
<span class="status-value compute-points">{{ compute_points.total|int }}</span>
|
563 |
</div>
|
564 |
<div class="status-item">
|
565 |
<span class="status-label">已使用</span>
|
566 |
+
<span class="status-value compute-points">{{ compute_points.used|int }}</span>
|
567 |
</div>
|
568 |
<div class="status-item">
|
569 |
<span class="status-label">剩余</span>
|
570 |
+
<span class="status-value compute-points">{{ compute_points.left|int }}</span>
|
571 |
</div>
|
572 |
<div class="status-item">
|
573 |
<span class="status-label">使用比例</span>
|
574 |
<div style="width: 100%; text-align: right;">
|
575 |
+
<span class="status-value compute-points {% if compute_points.percentage > 80 %}danger{% elif compute_points.percentage > 50 %}warning{% endif %}">
|
576 |
+
{{ compute_points.percentage }}%
|
577 |
</span>
|
578 |
<div class="progress-container">
|
579 |
+
<div class="progress-bar {% if compute_points.percentage > 80 %}danger{% elif compute_points.percentage > 50 %}warning{% endif %}" style="width: {{ compute_points.percentage }}%"></div>
|
|
|
580 |
</div>
|
581 |
</div>
|
582 |
</div>
|
583 |
+
{% if compute_points.last_update %}
|
584 |
<div class="status-item">
|
585 |
<span class="status-label">最后更新时间</span>
|
586 |
+
<span class="status-value">{{ compute_points.last_update.strftime('%Y-%m-%d %H:%M:%S') }}</span>
|
587 |
</div>
|
588 |
{% endif %}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
589 |
</div>
|
|
|
590 |
|
591 |
<div class="card">
|
592 |
<div class="card-header">
|
|
|
635 |
</div>
|
636 |
</div>
|
637 |
|
|
|
|
|
638 |
<div class="card">
|
639 |
<div class="card-header">
|
640 |
<h2 class="card-title">
|
641 |
<span class="card-icon">📊</span>
|
642 |
+
计算点使用日志
|
643 |
</h2>
|
644 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
645 |
<div class="table-container">
|
646 |
<table class="data-table">
|
647 |
<thead>
|
648 |
<tr>
|
649 |
+
{% for key, value in compute_points_log.columns.items() %}
|
650 |
<th>{{ value }}</th>
|
651 |
{% endfor %}
|
652 |
</tr>
|
653 |
</thead>
|
654 |
<tbody>
|
655 |
+
{% for entry in compute_points_log.log %}
|
656 |
<tr>
|
657 |
+
{% for key, value in compute_points_log.columns.items() %}
|
658 |
<td class="compute-points">{{ entry.get(key, 0) }}</td>
|
659 |
{% endfor %}
|
660 |
</tr>
|
|
|
662 |
</tbody>
|
663 |
</table>
|
664 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
665 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
666 |
|
667 |
<div class="card">
|
668 |
<div class="card-header">
|
|
|
769 |
// 初始化隐藏回到顶部按钮
|
770 |
document.querySelector('.float-btn').style.opacity = '0';
|
771 |
|
|
|
|
|
|
|
|
|
|
|
|
|
772 |
// 模型统计折叠功能
|
773 |
const toggleBtn = document.getElementById('toggleModelStats');
|
774 |
const hiddenModels = document.querySelectorAll('.hidden-model');
|