基线:全量源码首提(D1 版本控制落地,含第一轮优化 B1-B4/A1/A4/缩放修复)

This commit is contained in:
dqb-dev
2026-10-01 22:15:22 +08:00
commit 1e65792b09
499 changed files with 204579 additions and 0 deletions
+152
View File
@@ -0,0 +1,152 @@
# -*- coding: utf-8 -*-
"""一次性迁移:把 python 代理的 proxy_cache 展开成静态目录树 → bin\\Debug\\元件库网页\\
数据平移,不带旧服务逻辑。规则:
1. price_standalone.html / jquery.min.js 直接拷到根
2. 关键资源按【页面引用清单 override】精确落位(解决键名下划线歧义)
3. electricData/privateJson/electricPic/privateImg 各取最大缓存 → 固定路径(查询忽略)
4. webGetPrice 族(dx2_pcprice..._hash) → dx2_webGetPrice\\ 原键保存(server.cjs 按 infoJson hash 查)
5. 其余键:下划线全展开为目录树,同类多版本保留最新
"""
import os, re, shutil, sys
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
SRC = os.path.join(ROOT, "旧服务-python代理", "src")
CACHE = os.path.join(SRC, "proxy_cache")
PAGE_DIR = os.path.join(ROOT, "成套报价软件", "bin", "Debug", "元件库网页")
OUT = os.path.join(PAGE_DIR, "data") # 迁移只重建 data\;server.cjs/页面 在外层不动
# 键名 → 精确目标路径(页面/SDK 实际请求;键不带 .data 后缀)
OVERRIDE = {
"dian_open_api_css_jprice_public.min.css": "dian/open/api/css/jprice_public.min.css",
"open_api_css_jprice_public.min.css": "open/api/css/jprice_public.min.css",
"open_api_css_jprice.min.css": "open/api/css/jprice.min.css",
"dian_open_api_js_jprice-2.0.0.js": "dian/open/api/js/jprice-2.0.0.js",
"viewer2_preview_ztree_zTreeStyle.css": "viewer2/preview/ztree/zTreeStyle.css",
"viewer2_preview_ztree_preview.css": "viewer2/preview/ztree/preview.css",
"open_api_images_zTreeStandard.png": "open/api/images/zTreeStandard.png",
"images_nopic.png": "images/nopic.png",
}
def main():
if not os.path.isdir(CACHE):
print("!! 找不到 proxy_cache:", CACHE); sys.exit(1)
if os.path.isdir(OUT):
shutil.rmtree(OUT)
os.makedirs(OUT)
# 1. 页面与 jquery(放外层,与 server.cjs 同级)
for f in ("price_standalone.html", "jquery.min.js"):
shutil.copy2(os.path.join(SRC, f), os.path.join(PAGE_DIR, f))
print("OK 页面+jquery")
# 收集缓存键(去 .meta/.data,同名保留最新 mtime 的 .data)
entries = {} # 键 -> (data路径, mtime, size)
for name in os.listdir(CACHE):
if not name.endswith(".data"):
continue
key = name[:-5]
p = os.path.join(CACHE, name)
st = os.stat(p)
old = entries.get(key)
if old is None or st.st_mtime > old[1]:
entries[key] = (p, st.st_mtime, st.st_size)
print("缓存键总数:", len(entries))
# 2. webGetPrice 族 → 独立目录原键保存
n_wgp = 0
os.makedirs(os.path.join(OUT, "dx2_webGetPrice"), exist_ok=True)
for key, (p, _, _) in list(entries.items()):
if "webGetPrice" in key:
shutil.copy2(p, os.path.join(OUT, "dx2_webGetPrice", key + ".data"))
entries.pop(key); n_wgp += 1
print("OK webGetPrice:", n_wgp)
# 3. electricData 族:全部 ZIP 按内部文件名平移到 electricData_zips\(server.cjs 按 v 参数路由)
import zipfile
n_zip = 0
os.makedirs(os.path.join(OUT, "dian", "electricData_zips"), exist_ok=True)
for key in list(entries.keys()):
if "electricData" not in key:
continue
p = entries[key][0]
try:
z = zipfile.ZipFile(p)
inner = z.namelist()[0] if z.namelist() else ""
except Exception:
inner = ""
if not inner:
continue
base = inner[:-3] if inner.endswith(".js") else (inner[:-2] if inner.endswith("js") else inner)
base = base.rstrip(".")
dst = os.path.join(OUT, "dian", "electricData_zips", base + ".zip")
if not os.path.exists(dst):
shutil.copy2(p, dst)
n_zip += 1
entries.pop(key)
print("OK electricData ZIPs:", n_zip)
# electricPic 等取最大一份 → 固定路径
for 词, 目标 in [("privateJson", ("dian", "privateJson")),
("electricPic", ("dian", "electricPic")),
("privateImg", ("dian", "privateImg"))]:
best_key, best = None, None
for key, (p, mt, sz) in entries.items():
base = key.rsplit("/", 1)[-1]
名 = base.split("_")[0] if "_" in base else base
# 键形如 dian_electricData_xxxxxxxx / electricData
parts = key.split("_")
if 词 in parts or key == 词 or (parts and parts[0] == "dian" and len(parts) > 1 and parts[1].startswith(词)):
if best is None or sz > best[2]:
best_key, best = key, (p, mt, sz)
if best:
dst = os.path.join(OUT, *目标)
os.makedirs(os.path.dirname(dst), exist_ok=True)
shutil.copy2(best[0], dst)
entries.pop(best_key)
print("OK %s <- %s (%d B)" % (词, best_key, best[2]))
else:
print("!! %s 无缓存" % 词)
# 4. override 精确落位
n_ov = 0
for key, rel in OVERRIDE.items():
if key in entries:
dst = os.path.join(OUT, *rel.split("/"))
os.makedirs(os.path.dirname(dst), exist_ok=True)
shutil.copy2(entries[key][0], dst)
entries.pop(key); n_ov += 1
else:
# 有参数hash变体:找 键_hash
cand = [k for k in entries if k == key or k.startswith(key + "_")]
if cand:
cand.sort(key=lambda k: -entries[k][2])
k0 = cand[0]
dst = os.path.join(OUT, *rel.split("/"))
os.makedirs(os.path.dirname(dst), exist_ok=True)
shutil.copy2(entries[k0][0], dst)
entries.pop(k0); n_ov += 1
else:
print("!! override 缺缓存:", key)
print("OK override:", n_ov)
# 5. 其余全展开(下划线→斜杠);去掉 _参数hash 尾巴后仍带 8 位 hex 的整段保留
n_tree = 0
for key, (p, _, _) in entries.items():
rel = key.replace("_", "/")
dst = os.path.join(OUT, *rel.split("/"))
try:
os.makedirs(os.path.dirname(dst), exist_ok=True)
if os.path.exists(dst):
os.remove(dst)
shutil.copy2(p, dst)
n_tree += 1
except OSError:
pass # 非法文件名等跳过
print("OK 目录树:", n_tree)
total = sum(len(fs) for _, _, fs in os.walk(OUT))
size = sum(os.path.getsize(os.path.join(r, f)) for r, _, fs in os.walk(OUT) for f in fs)
print("完成: %d 文件, %.1f MB → %s" % (total, size / 1048576.0, OUT))
if __name__ == "__main__":
main()