#!/bin/bash set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" RUNTIME_DIR="${SUPPLIER_SUMMARY_RUNTIME_DIR:-$REPO_ROOT/runtime/private/supplier-summary-scheduler}" SOURCE_DIR="${SUPPLIER_SUMMARY_DIR:-$HOME/Desktop/加权平均单价}" CONTAINER="${SUPPLIER_SUMMARY_CONTAINER:-jiangling_app}" PASSWORD_FILE="${SUPPLIER_SUMMARY_PASSWORD_FILE:-$REPO_ROOT/runtime/private/supplier-summary-password}" SYSTEM_PYTHON="${SUPPLIER_SUMMARY_SYSTEM_PYTHON:-/usr/bin/python3}" CRYPTO_PYTHON="${SUPPLIER_SUMMARY_PYTHON:-$RUNTIME_DIR/venv/bin/python}" target_month="$(date -v-1m '+%Y-%m')" explicit_file='' notify=1 while [ "$#" -gt 0 ]; do case "$1" in --month) target_month="$2" shift ;; --file) explicit_file="$2" shift ;; --no-notify) notify=0 ;; *) printf '未知参数:%s\n' "$1" >&2 exit 2 ;; esac shift done if [[ ! "$target_month" =~ ^[0-9]{4}-[0-9]{2}$ ]]; then printf '月份格式应为 YYYY-MM:%s\n' "$target_month" >&2 exit 2 fi 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" work_dir="$(mktemp -d "${TMPDIR:-/tmp}/supplier-summary-import.XXXXXX")" container_file='' container_result='' cleanup() { if [ -n "$container_file" ]; then docker exec "$CONTAINER" unlink "$container_file" >/dev/null 2>&1 || true fi if [ -n "$container_result" ]; then docker exec "$CONTAINER" unlink "$container_result" >/dev/null 2>&1 || true fi rm -rf "$work_dir" } 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" local brief brief="$( "$SYSTEM_PYTHON" "$REPO_ROOT/scripts/summarize_supplier_summary_result.py" \ --month "$target_month" \ --result-json "$run_dir/result.json" \ --error "$message" 2>/dev/null )" || true [ -n "$brief" ] || brief="$target_month 导入失败:$message" printf '%s\n' "$brief" > "$run_dir/brief.txt" cp "$run_dir/result.json" "$RUNTIME_DIR/last-run.json" 2>/dev/null || true cp "$run_dir/result.json" "$history_dir/$timestamp.json" 2>/dev/null || true notify_user '供应商汇总导入失败' "$brief" printf '%s\n' "$brief" exit 1 } if [ -n "$explicit_file" ]; then source_file="$explicit_file" else source_file="$( "$SYSTEM_PYTHON" "$REPO_ROOT/scripts/find_supplier_summary.py" \ "$SOURCE_DIR" "$target_month" )" || record_failure "未找到 ${target_month} 的供应商汇总终版表" fi if [ ! -f "$source_file" ] || [ ! -r "$source_file" ]; then record_failure "供应商汇总文件不存在或不可读取:$source_file" fi if [ ! -x "$CRYPTO_PYTHON" ]; then record_failure "解密环境未安装,请先运行 scripts/install-supplier-summary-schedule-macos.sh" fi if [ ! -f "$PASSWORD_FILE" ]; then record_failure "供应商汇总表密码文件不存在:$PASSWORD_FILE" fi if ! command -v docker >/dev/null 2>&1; then record_failure "找不到 docker 命令,无法导入本地容器" fi source_name="$(basename "$source_file")" decrypted_file="$work_dir/$source_name" printf '开始导入供应商汇总:月份=%s,文件=%s\n' "$target_month" "$source_name" \ | tee "$run_dir/run.log" "$CRYPTO_PYTHON" "$REPO_ROOT/scripts/decrypt_supplier_summary.py" \ "$source_file" "$decrypted_file" \ --password-file "$PASSWORD_FILE" >> "$run_dir/run.log" 2>&1 \ || record_failure "供应商汇总文件解密失败,请确认密码及文件完整性" chmod 644 "$decrypted_file" container_file="/tmp/supplier-summary-$timestamp.xlsx" container_result="/tmp/supplier-summary-$timestamp.json" docker cp "$decrypted_file" "$CONTAINER:$container_file" >> "$run_dir/run.log" 2>&1 \ || record_failure "无法将解密后的供应商汇总文件传入本地应用容器" docker exec "$CONTAINER" chmod 644 "$container_file" >> "$run_dir/run.log" 2>&1 \ || record_failure "无法设置容器内供应商汇总文件权限" set +e docker exec -u www-data -e HOME=/tmp "$CONTAINER" \ php artisan inventory:supplier-summary:import "$container_file" \ --month="$target_month" \ --result-json="$container_result" \ >> "$run_dir/import.log" 2>&1 import_exit=$? set -e if ! docker cp "$CONTAINER:$container_result" "$work_dir/result.json" >> "$run_dir/run.log" 2>&1; then record_failure "导入命令未生成结果文件,退出码:$import_exit" fi set +e brief="$( "$SYSTEM_PYTHON" "$REPO_ROOT/scripts/summarize_supplier_summary_result.py" \ --month "$target_month" \ --result-json "$run_dir/result.json" \ --input "$work_dir/result.json" )" summary_exit=$? set -e printf '%s\n' "$brief" | tee "$run_dir/brief.txt" cp "$run_dir/result.json" "$RUNTIME_DIR/last-run.json" cp "$run_dir/result.json" "$history_dir/$timestamp.json" if [ "$import_exit" -ne 0 ] || [ "$summary_exit" -ne 0 ]; then notify_user '供应商汇总导入需处理' "$brief" exit 1 fi notify_user '供应商汇总导入完成' "$brief" exit 0