- 任务详情上传支持"本批素材无条码"开关,跳过条码必填校验 - SKU卡片/主图网格从4列改5列,图片高度压缩,去掉冗余标签和提示 - 详情图/PSD上传区去掉大占位框,改成紧凑按钮+标签 - 补充历史导入相关脚本和工具文件 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
124 lines
4.0 KiB
Python
124 lines
4.0 KiB
Python
#!/usr/bin/env python3
|
||
import argparse
|
||
import csv
|
||
import sqlite3
|
||
from pathlib import Path
|
||
|
||
|
||
EXPORT_HEADERS = [
|
||
("root_path", "source_root(来源根路径)"),
|
||
("spu", "spu(SPU)"),
|
||
("directory_name", "directory_name(目录名称)"),
|
||
("relative_path", "relative_path(相对路径)"),
|
||
("windows_path", "windows_path(Windows路径)"),
|
||
("sku_dir_path", "sku_dir_path(SKU目录完整路径)"),
|
||
("parent_path", "parent_path(上级目录)"),
|
||
("grandparent_path", "grandparent_path(上上级目录)"),
|
||
("depth", "depth(目录层级)"),
|
||
("file_count", "file_count(文件数)"),
|
||
("image_count", "image_count(图片数)"),
|
||
("child_dir_count", "child_dir_count(子目录数)"),
|
||
("has_detail_dir_sibling", "has_detail_dir_sibling(同级有详情页或images)"),
|
||
("has_main_dir_sibling", "has_main_dir_sibling(同级有主图)"),
|
||
("has_detail_and_main_siblings", "has_detail_and_main_siblings(同级同时有详情页和主图)"),
|
||
("sibling_detail_dir_names_json", "sibling_detail_dir_names_json(同级详情目录)"),
|
||
("sibling_main_dir_names_json", "sibling_main_dir_names_json(同级主图目录)"),
|
||
("sibling_dir_names_json", "sibling_dir_names_json(同级全部目录)"),
|
||
("sample_files_json", "sample_files_json(示例文件)"),
|
||
("created_at", "created_at(创建时间)"),
|
||
("scan_id", "scan_id(扫描批次ID)"),
|
||
]
|
||
|
||
|
||
def parse_args():
|
||
parser = argparse.ArgumentParser(description="Export sku folder scan results from sqlite to CSV.")
|
||
parser.add_argument(
|
||
"--db-path",
|
||
default="/root/gongxiangp2/output/history-sku-folders.db",
|
||
help="SQLite database file path.",
|
||
)
|
||
parser.add_argument(
|
||
"--output",
|
||
default="历史SKU目录清单.csv",
|
||
help="Output CSV path.",
|
||
)
|
||
parser.add_argument(
|
||
"--scan-id",
|
||
default="",
|
||
help="Optional scan_id filter. Empty means export all rows.",
|
||
)
|
||
parser.add_argument(
|
||
"--only-detail-main",
|
||
action="store_true",
|
||
help="Only export rows whose sibling folders contain both detail/images and main image folders.",
|
||
)
|
||
return parser.parse_args()
|
||
|
||
|
||
def main():
|
||
args = parse_args()
|
||
output_path = Path(args.output)
|
||
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||
|
||
conn = sqlite3.connect(args.db_path)
|
||
conn.row_factory = sqlite3.Row
|
||
try:
|
||
where_clauses = []
|
||
params = []
|
||
|
||
if args.scan_id:
|
||
where_clauses.append("scan_id = ?")
|
||
params.append(args.scan_id)
|
||
|
||
if args.only_detail_main:
|
||
where_clauses.append("has_detail_and_main_siblings = 1")
|
||
|
||
where_sql = ""
|
||
if where_clauses:
|
||
where_sql = "WHERE " + " AND ".join(where_clauses)
|
||
|
||
query = f"""
|
||
SELECT
|
||
scan_id,
|
||
root_path,
|
||
spu,
|
||
directory_name,
|
||
relative_path,
|
||
sku_dir_path AS windows_path,
|
||
sku_dir_path,
|
||
parent_path,
|
||
grandparent_path,
|
||
depth,
|
||
file_count,
|
||
image_count,
|
||
child_dir_count,
|
||
has_detail_dir_sibling,
|
||
has_main_dir_sibling,
|
||
has_detail_and_main_siblings,
|
||
sibling_detail_dir_names_json,
|
||
sibling_main_dir_names_json,
|
||
sibling_dir_names_json,
|
||
sample_files_json,
|
||
created_at
|
||
FROM sku_folder_scan_items
|
||
{where_sql}
|
||
ORDER BY root_path, relative_path
|
||
"""
|
||
|
||
rows = conn.execute(query, params).fetchall()
|
||
|
||
with output_path.open("w", encoding="utf-8-sig", newline="") as handle:
|
||
writer = csv.writer(handle)
|
||
writer.writerow([header for _, header in EXPORT_HEADERS])
|
||
for row in rows:
|
||
writer.writerow([row[column] for column, _ in EXPORT_HEADERS])
|
||
|
||
print(f"exported_rows={len(rows)}")
|
||
print(f"output={output_path}")
|
||
finally:
|
||
conn.close()
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|