修改config
This commit is contained in:
parent
5e68d97127
commit
1890a8380b
@ -24,25 +24,26 @@ app = Flask(__name__, static_folder="../frontend", static_url_path="/static")
|
|||||||
CORS(app)
|
CORS(app)
|
||||||
|
|
||||||
base_dir = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
|
base_dir = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
|
||||||
default_db_path = os.path.join(base_dir, "data", "data.db")
|
db_path = os.path.join(base_dir, "data", "data.db")
|
||||||
if os.name == 'nt':
|
db_url_env = os.getenv('DATABASE_URL')
|
||||||
default_db_url = f"sqlite:///{default_db_path}"
|
if db_url_env:
|
||||||
|
app.config['SQLALCHEMY_DATABASE_URI'] = db_url_env
|
||||||
else:
|
else:
|
||||||
default_db_url = f"sqlite:////{default_db_path}"
|
if os.name == 'nt':
|
||||||
db_url = os.getenv('DATABASE_URL') or default_db_url
|
app.config['SQLALCHEMY_DATABASE_URI'] = f"sqlite:///{db_path}"
|
||||||
app.config['SQLALCHEMY_DATABASE_URI'] = db_url
|
else:
|
||||||
|
app.config['SQLALCHEMY_DATABASE_URI'] = f"sqlite:////{db_path}"
|
||||||
|
|
||||||
def _ensure_sqlite_dir(url: str):
|
def _ensure_sqlite_dir():
|
||||||
if not isinstance(url, str) or not url.startswith('sqlite'):
|
d = os.path.dirname(db_path)
|
||||||
return
|
if not os.path.exists(d):
|
||||||
p = url.replace('sqlite:////', '/').replace('sqlite:///', '')
|
|
||||||
d = os.path.dirname(p)
|
|
||||||
if d and not os.path.exists(d):
|
|
||||||
os.makedirs(d, exist_ok=True)
|
os.makedirs(d, exist_ok=True)
|
||||||
|
|
||||||
_ensure_sqlite_dir(db_url)
|
_ensure_sqlite_dir()
|
||||||
db = SQLAlchemy(app)
|
db = SQLAlchemy(app)
|
||||||
|
|
||||||
|
scheduler = None
|
||||||
|
|
||||||
class DailyRevenue(db.Model):
|
class DailyRevenue(db.Model):
|
||||||
__tablename__ = 'daily_revenue'
|
__tablename__ = 'daily_revenue'
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
@ -106,15 +107,16 @@ def daily_job(target_date=None):
|
|||||||
if target_date is None:
|
if target_date is None:
|
||||||
target_date = datetime.now().date()
|
target_date = datetime.now().date()
|
||||||
|
|
||||||
existing = DailyRevenue.query.filter_by(date=target_date).first()
|
existing = DailyRevenue.query.filter_by(date=target_date).first()
|
||||||
if existing:
|
if existing:
|
||||||
if not existing.is_final:
|
if not existing.is_final:
|
||||||
existing.is_final = True
|
existing.is_final = True
|
||||||
existing.source = existing.source or 'generator'
|
existing.source = existing.source or 'generator'
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
# 补推消息
|
push_feishu(target_date.isoformat(), existing.amount, "daily_finalize")
|
||||||
push_feishu(target_date.isoformat(), existing.amount, "daily_finalize")
|
else:
|
||||||
return
|
push_feishu(target_date.isoformat(), existing.amount, "daily_exists")
|
||||||
|
return
|
||||||
|
|
||||||
amount = gen_amount_for_date(target_date, cfg)
|
amount = gen_amount_for_date(target_date, cfg)
|
||||||
rev = DailyRevenue(date=target_date, amount=amount, is_final=True, source='generator')
|
rev = DailyRevenue(date=target_date, amount=amount, is_final=True, source='generator')
|
||||||
@ -328,6 +330,38 @@ def api_series7():
|
|||||||
cur += timedelta(days=1)
|
cur += timedelta(days=1)
|
||||||
return jsonify(series)
|
return jsonify(series)
|
||||||
|
|
||||||
|
@app.route('/api/admin/reload_cutoff', methods=['POST'])
|
||||||
|
def admin_reload_cutoff():
|
||||||
|
token = os.getenv('ADMIN_TOKEN')
|
||||||
|
if token and request.headers.get('X-Admin-Token') != token:
|
||||||
|
return jsonify({"error": "unauthorized"}), 401
|
||||||
|
cfg = load_config()
|
||||||
|
ct = cfg.get("cutoff_time")
|
||||||
|
ch = cfg.get("cutoff_hour", 23)
|
||||||
|
cm = 0
|
||||||
|
if isinstance(ct, str) and re.match(r'^\d{1,2}:\d{2}$', ct):
|
||||||
|
try:
|
||||||
|
p = ct.split(':')
|
||||||
|
ch = int(p[0]); cm = int(p[1])
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
ch = int(ch)
|
||||||
|
except Exception:
|
||||||
|
ch = 23
|
||||||
|
if ch < 0 or ch > 23:
|
||||||
|
ch = 23
|
||||||
|
if cm < 0 or cm > 59:
|
||||||
|
cm = 0
|
||||||
|
global scheduler
|
||||||
|
if scheduler:
|
||||||
|
try:
|
||||||
|
scheduler.add_job(daily_job, "cron", hour=ch, minute=cm, id="daily", replace_existing=True)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
settle_today_if_due()
|
||||||
|
return jsonify({"ok": True, "cutoff_time": f"{ch:02d}:{cm:02d}"})
|
||||||
|
|
||||||
@app.route("/api/revenue")
|
@app.route("/api/revenue")
|
||||||
def api_revenue():
|
def api_revenue():
|
||||||
"""查询历史营业额"""
|
"""查询历史营业额"""
|
||||||
@ -508,7 +542,7 @@ if __name__ == "__main__":
|
|||||||
ch = 23
|
ch = 23
|
||||||
if cm < 0 or cm > 59:
|
if cm < 0 or cm > 59:
|
||||||
cm = 0
|
cm = 0
|
||||||
scheduler.add_job(daily_job, "cron", hour=ch, minute=cm)
|
scheduler.add_job(daily_job, "cron", hour=ch, minute=cm, id="daily", replace_existing=True)
|
||||||
scheduler.start()
|
scheduler.start()
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
sync_log_to_db()
|
sync_log_to_db()
|
||||||
|
|||||||
@ -12,4 +12,5 @@ services:
|
|||||||
- AUTO_IMPORT_ON_START=1
|
- AUTO_IMPORT_ON_START=1
|
||||||
volumes:
|
volumes:
|
||||||
- ./data:/app/data:Z
|
- ./data:/app/data:Z
|
||||||
|
- ./config.json:/app/config.json:ro
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|||||||
25
scripts/deploy.ps1
Normal file
25
scripts/deploy.ps1
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
param(
|
||||||
|
[string]$RepoUrl = "",
|
||||||
|
[string]$Branch = "main",
|
||||||
|
[string]$RepoDir = ".",
|
||||||
|
[string]$ComposeFile = "docker-compose.yml",
|
||||||
|
[string]$BaseUrl = "http://localhost:57778",
|
||||||
|
[string]$AdminToken = ""
|
||||||
|
)
|
||||||
|
if (!(Test-Path $RepoDir)) { New-Item -ItemType Directory -Path $RepoDir | Out-Null }
|
||||||
|
if (!(Test-Path (Join-Path $RepoDir ".git"))) {
|
||||||
|
if ($RepoUrl -eq "") { throw "RepoUrl is required for clone" }
|
||||||
|
git clone -b $Branch $RepoUrl $RepoDir
|
||||||
|
}
|
||||||
|
Set-Location $RepoDir
|
||||||
|
git remote set-url origin $RepoUrl
|
||||||
|
git fetch origin
|
||||||
|
git checkout $Branch
|
||||||
|
git pull origin $Branch
|
||||||
|
if (!(Test-Path $ComposeFile)) { throw "compose not found: $ComposeFile" }
|
||||||
|
docker compose -f $ComposeFile up -d --build
|
||||||
|
$headers = @{}
|
||||||
|
if ($AdminToken -ne "") { $headers["X-Admin-Token"] = $AdminToken }
|
||||||
|
try { Invoke-RestMethod -Method Post -Uri "$BaseUrl/api/admin/reload_cutoff" -Headers $headers | Out-Null } catch { }
|
||||||
|
try { Invoke-RestMethod -Method Get -Uri "$BaseUrl/api/metrics" | ConvertTo-Json -Depth 3 | Write-Output } catch { }
|
||||||
|
try { Invoke-RestMethod -Method Post -Uri "$BaseUrl/api/admin/test_push" -Headers $headers | ConvertTo-Json -Depth 3 | Write-Output } catch { }
|
||||||
25
scripts/deploy.sh
Normal file
25
scripts/deploy.sh
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
REPO_URL=${1:-}
|
||||||
|
BRANCH=${2:-main}
|
||||||
|
REPO_DIR=${3:-.}
|
||||||
|
COMPOSE_FILE=${4:-docker-compose.yml}
|
||||||
|
BASE_URL=${5:-http://localhost:57778}
|
||||||
|
ADMIN_TOKEN=${6:-}
|
||||||
|
mkdir -p "$REPO_DIR"
|
||||||
|
if [ ! -d "$REPO_DIR/.git" ]; then
|
||||||
|
[ -z "$REPO_URL" ] && { echo "RepoUrl required"; exit 1; }
|
||||||
|
git clone -b "$BRANCH" "$REPO_URL" "$REPO_DIR"
|
||||||
|
fi
|
||||||
|
cd "$REPO_DIR"
|
||||||
|
git remote set-url origin "$REPO_URL"
|
||||||
|
git fetch origin
|
||||||
|
git checkout "$BRANCH"
|
||||||
|
git pull origin "$BRANCH"
|
||||||
|
[ -f "$COMPOSE_FILE" ] || { echo "compose not found: $COMPOSE_FILE"; exit 1; }
|
||||||
|
docker compose -f "$COMPOSE_FILE" up -d --build
|
||||||
|
HDR=( )
|
||||||
|
if [ -n "$ADMIN_TOKEN" ]; then HDR=( -H "X-Admin-Token: $ADMIN_TOKEN" ); fi
|
||||||
|
curl -s -X POST "${BASE_URL}/api/admin/reload_cutoff" "${HDR[@]}" || true
|
||||||
|
curl -s "${BASE_URL}/api/metrics" || true
|
||||||
|
curl -s -X POST "${BASE_URL}/api/admin/test_push" "${HDR[@]}" || true
|
||||||
Loading…
Reference in New Issue
Block a user