126 lines
3.5 KiB
Bash
Executable File
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
|