优化界面布局: 简化短信列表,增强统计信息详情
Changes: - 短信列表: 简化为列表视图,只显示号码、时间、完整内容 - 统计信息: 最近接收增加详细参数(签名、IP、详情链接) - 统计信息: 显示从10条增加到20条 - 优化CSS样式,提升可读性
This commit is contained in:
2
app.py
2
app.py
@@ -230,7 +230,7 @@ def register_routes(app, db):
|
|||||||
def statistics():
|
def statistics():
|
||||||
"""统计信息"""
|
"""统计信息"""
|
||||||
stats = db.get_statistics()
|
stats = db.get_statistics()
|
||||||
recent = db.get_recent_messages(10)
|
recent = db.get_recent_messages(20)
|
||||||
from_numbers = db.get_from_numbers()
|
from_numbers = db.get_from_numbers()
|
||||||
|
|
||||||
return render_template('statistics.html',
|
return render_template('statistics.html',
|
||||||
|
|||||||
15
nohup.out
Normal file
15
nohup.out
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
[2026-02-06 23:52:11,314] INFO in app: 启动短信接收服务 (环境: development)
|
||||||
|
[2026-02-06 23:52:11,314] INFO in app: 启动短信接收服务 (环境: development)
|
||||||
|
[2026-02-06 23:52:11,314] INFO in app: 数据库: /root/.openclaw/workspace/sms-receiver/sms_receiver.db
|
||||||
|
[2026-02-06 23:52:11,314] INFO in app: 数据库: /root/.openclaw/workspace/sms-receiver/sms_receiver.db
|
||||||
|
[2026-02-06 23:52:11,314] INFO in app: 监听端口: 9518
|
||||||
|
[2026-02-06 23:52:11,314] INFO in app: 监听端口: 9518
|
||||||
|
[2026-02-06 23:52:11,315] INFO in app: 登录已启用: True
|
||||||
|
[2026-02-06 23:52:11,315] INFO in app: 登录已启用: True
|
||||||
|
* Serving Flask app 'app'
|
||||||
|
* Debug mode: off
|
||||||
|
[31m[1mWARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.[0m
|
||||||
|
* Running on all addresses (0.0.0.0)
|
||||||
|
* Running on http://127.0.0.1:9518
|
||||||
|
* Running on http://199.188.198.12:9518
|
||||||
|
[33mPress CTRL+C to quit[0m
|
||||||
17
sms_receiver.service
Normal file
17
sms_receiver.service
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=SMS Receiver Web Service
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=forking
|
||||||
|
User=root
|
||||||
|
WorkingDirectory=/root/.openclaw/workspace/sms-receiver
|
||||||
|
ExecStart=/root/.openclaw/workspace/sms-receiver/sms_receiverctl.sh start
|
||||||
|
ExecStop=/root/.openclaw/workspace/sms-receiver/sms_receiverctl.sh stop
|
||||||
|
ExecReload=/root/.openclaw/workspace/sms-receiver/sms_receiverctl.sh restart
|
||||||
|
PIDFile=/root/.openclaw/workspace/sms-receiver/sms_receiver.pid
|
||||||
|
Restart=always
|
||||||
|
RestartSec=5
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
90
sms_receiverctl.sh
Executable file
90
sms_receiverctl.sh
Executable file
@@ -0,0 +1,90 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# 短信转发接收端 - 启动/停止/重启/状态脚本
|
||||||
|
|
||||||
|
APP_DIR="/root/.openclaw/workspace/sms-receiver"
|
||||||
|
APP_FILE="$APP_DIR/app.py"
|
||||||
|
PIDFILE="$APP_DIR/sms_receiver.pid"
|
||||||
|
LOGFILE="$APP_DIR/sms_receiver.log"
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
if [ -f "$PIDFILE" ]; then
|
||||||
|
PID=$(cat "$PIDFILE")
|
||||||
|
if ps -p "$PID" > /dev/null 2>&1; then
|
||||||
|
echo "服务已在运行 (PID: $PID)"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
rm -f "$PIDFILE"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "启动短信转发接收端..."
|
||||||
|
cd "$APP_DIR"
|
||||||
|
nohup python3 app.py > "$LOGFILE" 2>&1 &
|
||||||
|
echo $! > "$PIDFILE"
|
||||||
|
echo "服务已启动 (PID: $(cat $PIDFILE))"
|
||||||
|
echo "日志文件: $LOGFILE"
|
||||||
|
echo "监听地址: http://0.0.0.0:9518"
|
||||||
|
;;
|
||||||
|
|
||||||
|
stop)
|
||||||
|
if [ ! -f "$PIDFILE" ]; then
|
||||||
|
echo "服务未运行"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
PID=$(cat "$PIDFILE")
|
||||||
|
echo "停止服务 (PID: $PID)..."
|
||||||
|
kill "$PID" 2>/dev/null
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
if ps -p "$PID" > /dev/null 2>&1; then
|
||||||
|
echo "强制停止..."
|
||||||
|
kill -9 "$PID" 2>/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -f "$PIDFILE"
|
||||||
|
echo "服务已停止"
|
||||||
|
;;
|
||||||
|
|
||||||
|
restart)
|
||||||
|
$0 stop
|
||||||
|
sleep 2
|
||||||
|
$0 start
|
||||||
|
;;
|
||||||
|
|
||||||
|
status)
|
||||||
|
if [ -f "$PIDFILE" ]; then
|
||||||
|
PID=$(cat "$PIDFILE")
|
||||||
|
if ps -p "$PID" > /dev/null 2>&1; then
|
||||||
|
echo "服务正在运行 (PID: $PID)"
|
||||||
|
echo "启动时间: $(ps -p $PID -o lstart=)"
|
||||||
|
echo "内存使用: $(ps -p $PID -o rss= | awk '{print int($1/1024)"MB"}')"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo "PID 文件存在但进程未运行,清理..."
|
||||||
|
rm -f "$PIDFILE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "服务未运行"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
log)
|
||||||
|
tail -f "$LOGFILE"
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo "用法: $0 {start|stop|restart|status|log}"
|
||||||
|
echo ""
|
||||||
|
echo "命令说明:"
|
||||||
|
echo " start - 启动服务"
|
||||||
|
echo " stop - 停止服务"
|
||||||
|
echo " restart - 重启服务"
|
||||||
|
echo " status - 查看状态"
|
||||||
|
echo " log - 查看实时日志"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
@@ -138,26 +138,54 @@
|
|||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
}
|
}
|
||||||
|
|
||||||
.messages-table th,
|
.messages-list {
|
||||||
.messages-table td {
|
background: white;
|
||||||
padding: 12px 15px;
|
border-radius: 10px;
|
||||||
text-align: left;
|
overflow: hidden;
|
||||||
|
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-view {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-view li {
|
||||||
|
padding: 15px;
|
||||||
border-bottom: 1px solid #eee;
|
border-bottom: 1px solid #eee;
|
||||||
|
transition: background 0.3s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.messages-table th {
|
.list-view li:hover {
|
||||||
background: #f5f5f5;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.messages-table tr:hover {
|
|
||||||
background: #f9f9f9;
|
background: #f9f9f9;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.list-view li:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.msg-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
.from-number {
|
.from-number {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #667eea;
|
color: #667eea;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.msg-time {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.msg-content {
|
||||||
|
color: #333;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.6;
|
||||||
|
word-break: break-all;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sign-verified {
|
.sign-verified {
|
||||||
@@ -351,40 +379,19 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="messages-table">
|
<div class="messages-list">
|
||||||
{% if messages %}
|
{% if messages %}
|
||||||
<table>
|
<ul class="list-view">
|
||||||
<thead>
|
{% for msg in messages %}
|
||||||
<tr>
|
<li>
|
||||||
<th>ID</th>
|
<div class="msg-header">
|
||||||
<th>发送方</th>
|
<span class="from-number">{{ msg.from_number }}</span>
|
||||||
<th>内容</th>
|
<span class="msg-time">{{ msg.created_at }}</span>
|
||||||
<th>时间</th>
|
</div>
|
||||||
<th>验证</th>
|
<div class="msg-content">{{ msg.content }}</div>
|
||||||
</tr>
|
</li>
|
||||||
</thead>
|
{% endfor %}
|
||||||
<tbody>
|
</ul>
|
||||||
{% for msg in messages %}
|
|
||||||
<tr>
|
|
||||||
<td>{{ msg.id }}</td>
|
|
||||||
<td><span class="from-number">{{ msg.from_number }}</span></td>
|
|
||||||
<td>
|
|
||||||
<a href="/message/{{ msg.id }}" style="color: #333; text-decoration: none;">
|
|
||||||
{{ msg.content[:50] }}{% if msg.content|length > 50 %}...{% endif %}
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td>{{ msg.created_at }}</td>
|
|
||||||
<td>
|
|
||||||
{% if msg.sign_verified %}
|
|
||||||
<span class="sign-verified yes">✓ 已验证</span>
|
|
||||||
{% else %}
|
|
||||||
<span class="sign-verified no">✗ 未验证</span>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="empty-state">
|
<div class="empty-state">
|
||||||
<h3>暂无短信数据</h3>
|
<h3>暂无短信数据</h3>
|
||||||
|
|||||||
@@ -95,33 +95,102 @@
|
|||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.recent-list {
|
.detailed-list {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.recent-list li {
|
.detailed-list li {
|
||||||
padding: 15px;
|
padding: 20px;
|
||||||
border-bottom: 1px solid #eee;
|
border-bottom: 1px solid #eee;
|
||||||
|
transition: background 0.3s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.recent-list li:last-child {
|
.detailed-list li:last-child {
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.recent-list .from {
|
.detailed-list li:hover {
|
||||||
font-weight: bold;
|
background: #f9f9f9;
|
||||||
color: #667eea;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.recent-list .time {
|
.detailed-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detailed-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detailed-id {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #999;
|
color: #999;
|
||||||
margin-left: 10px;
|
background: #f0f0f0;
|
||||||
|
padding: 2px 8px;
|
||||||
|
border-radius: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.recent-list .content {
|
.from-number {
|
||||||
|
font-weight: bold;
|
||||||
|
color: #667eea;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.msg-time {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detailed-content {
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.msg-detail {
|
||||||
color: #333;
|
color: #333;
|
||||||
margin-top: 5px;
|
font-size: 14px;
|
||||||
|
line-height: 1.6;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
.msg-meta {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meta-tag {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-link {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #667eea;
|
||||||
|
text-decoration: none;
|
||||||
|
padding: 4px 10px;
|
||||||
|
background: #f0f0f0;
|
||||||
|
border-radius: 3px;
|
||||||
|
transition: all 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-link:hover {
|
||||||
|
background: #667eea;
|
||||||
|
color: white;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sign-verified {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 4px 10px;
|
||||||
|
border-radius: 12px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.numbers-list {
|
.numbers-list {
|
||||||
@@ -213,17 +282,37 @@
|
|||||||
<div class="section">
|
<div class="section">
|
||||||
<h3>📬 最近接收</h3>
|
<h3>📬 最近接收</h3>
|
||||||
{% if recent %}
|
{% if recent %}
|
||||||
<ul class="recent-list">
|
<ul class="detailed-list">
|
||||||
{% for msg in recent %}
|
{% for msg in recent %}
|
||||||
<li>
|
<li>
|
||||||
<span class="from">{{ msg.from_number }}</span>
|
<div class="detailed-header">
|
||||||
<span class="time">{{ msg.created_at }}</span>
|
<div class="detailed-info">
|
||||||
<div class="content">{{ msg.content[:100] }}{% if msg.content|length > 100 %}...{% endif %}</div>
|
<span class="from-number">{{ msg.from_number }}</span>
|
||||||
|
<span class="detailed-id">ID: {{ msg.id }}</span>
|
||||||
|
</div>
|
||||||
|
<span class="msg-time">{{ msg.created_at }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="detailed-content">
|
||||||
|
<div class="msg-detail">{{ msg.content }}</div>
|
||||||
|
<div class="msg-meta">
|
||||||
|
<span class="meta-tag">
|
||||||
|
{% if msg.sign_verified %}
|
||||||
|
<span class="sign-verified yes">✓ 已验证</span>
|
||||||
|
{% else %}
|
||||||
|
<span class="sign-verified no">✗ 未验证</span>
|
||||||
|
{% endif %}
|
||||||
|
</span>
|
||||||
|
{% if msg.ip_address %}
|
||||||
|
<span class="meta-tag">🌐 {{ msg.ip_address }}</span>
|
||||||
|
{% endif %}
|
||||||
|
<a href="/message/{{ msg.id }}" class="detail-link">查看详情</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
{% else %}
|
{% else %}
|
||||||
暂无数据
|
暂无数据
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user