CaiWuXiTong/scripts/run-product-monthly-weighted-average-macos.sh

126 lines
3.5 KiB
Bash
Executable File

#!/bin/bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
RUNTIME_DIR="${PRODUCT_WEIGHTED_AVERAGE_RUNTIME_DIR:-$REPO_ROOT/runtime/private/product-monthly-weighted-average-scheduler}"
CONTAINER="${PRODUCT_WEIGHTED_AVERAGE_CONTAINER:-jiangling_app}"
SYSTEM_PYTHON="${PRODUCT_WEIGHTED_AVERAGE_SYSTEM_PYTHON:-/usr/bin/python3}"
month=''
notify=1
while [ "$#" -gt 0 ]; do
case "$1" in
--month)
month="$2"
shift
;;
--no-notify)
notify=0
;;
*)
printf '未知参数:%s\n' "$1" >&2
exit 2
;;
esac
shift
done
timestamp="$(date '+%Y%m%dT%H%M%S')"
run_dir="$RUNTIME_DIR/runs/$timestamp"
history_dir="$RUNTIME_DIR/history"
mkdir -p "$run_dir" "$history_dir"
container_result="/tmp/product-weighted-average-$timestamp.json"
cleanup() {
docker exec "$CONTAINER" unlink "$container_result" >/dev/null 2>&1 || true
}
trap cleanup EXIT
notify_user() {
local title="$1"
local message="$2"
if [ "$notify" -eq 1 ] && command -v osascript >/dev/null 2>&1; then
osascript \
-e 'on run argv' \
-e 'display notification (item 2 of argv) with title (item 1 of argv)' \
-e 'end run' \
"$title" "$message" >/dev/null 2>&1 || true
fi
}
record_failure() {
local message="$1"
"$SYSTEM_PYTHON" - "$message" "$run_dir/result.json" "${month:-latest}" <<'PY'
import json
import sys
from pathlib import Path
message, output, month = sys.argv[1:]
result = {
"status": "failed",
"report_month": "" if month == "latest" else month + "-01",
"message": message,
}
Path(output).write_text(
json.dumps(result, ensure_ascii=False, indent=2) + "\n",
encoding="utf-8",
)
PY
cp "$run_dir/result.json" "$RUNTIME_DIR/last-run.json"
cp "$run_dir/result.json" "$history_dir/$timestamp.json"
notify_user '商品月加权平均单价失败' "$message"
printf '%s\n' "$message"
exit 1
}
if ! command -v docker >/dev/null 2>&1; then
record_failure '找不到 docker 命令,无法执行商品月加权平均单价。'
fi
args=(php artisan finance:monthly-weighted-product-cost:auto)
if [ -n "$month" ]; then
args+=("--month=$month")
fi
args+=("--result-json=$container_result")
set +e
docker exec -u www-data -e HOME=/tmp "$CONTAINER" "${args[@]}" \
> "$run_dir/run.log" 2>&1
auto_exit=$?
set -e
if ! docker cp "$CONTAINER:$container_result" "$run_dir/result.json" >> "$run_dir/run.log" 2>&1; then
tail -20 "$run_dir/run.log" >&2 || true
record_failure "自动计算未生成结果文件,退出码:$auto_exit"
fi
"$SYSTEM_PYTHON" "$REPO_ROOT/scripts/summarize_product_weighted_average_result.py" \
--input "$run_dir/result.json" \
--result-json "$RUNTIME_DIR/last-run.json" > "$run_dir/brief.txt"
cp "$RUNTIME_DIR/last-run.json" "$history_dir/$timestamp.json"
brief="$(cat "$run_dir/brief.txt")"
printf '%s\n' "$brief"
result_status="$("$SYSTEM_PYTHON" - "$run_dir/result.json" <<'PY'
import json
import sys
from pathlib import Path
print(json.loads(Path(sys.argv[1]).read_text(encoding="utf-8")).get("status", "failed"))
PY
)"
if [ "$auto_exit" -ne 0 ] || [ "$result_status" = 'blocked' ] || [ "$result_status" = 'failed' ]; then
notify_user '商品月加权平均单价未完成' "$brief"
exit 1
fi
if [ "$result_status" = 'review_required' ]; then
notify_user '商品月加权平均单价需复核' "$brief"
exit 0
fi
notify_user '商品月加权平均单价完成' "$brief"
exit 0