167 lines
5.5 KiB
Bash
Executable File
167 lines
5.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="${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
|