上线版: 产品表单统一+form嵌套修复+用户管理+部署+三套叙事

- 产品编辑入口统一走 ProductFormFull(卖点/风格/人群/品牌词全字段);
  修复开任务页 <form> 套 <form> 致"编辑产品"报错、改不了、跳回首个产品
- dashboard 入口卡片对齐实际路由: 系统管理(/config) 与 工作配置(/settings) 分开;
  settings ?tab=products 直达改用挂载后读 URL, 消除 hydration mismatch
- 新增用户管理(users API/admin service/改密页) + alembic 022/023/024
- 上线部署: Dockerfile / docker-compose.prod+https / nginx https / .env.example
- A8 三套正交叙事(痛点/场景/成分背书) + beige 调色去AI化 + 飞轮 text_import 高权重信号

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
yangqianqian
2026-06-30 18:08:13 +08:00
parent a77212781c
commit df1856d793
150 changed files with 8616 additions and 1765 deletions

View File

@@ -21,6 +21,9 @@ except ImportError:
_PILLOW_OK = False
logger.warning("Pillow 未安装image_postprocessor 不可用")
# 北哥暖棕调色层A4自带开关与降级
from .beige_color_grade import grade as _beige_grade, is_enabled as _beige_enabled
# 比例映射表,对齐大卫 RATIO_MAP。key 为字符串如 '3:4'
RATIO_MAP: dict[str, tuple[int, int]] = {
"1:1": (1024, 1024),
@@ -74,12 +77,27 @@ def process_image(
img = ImageOps.fit(img, (tw, th), method=Image.LANCZOS)
logger.debug("resize %dx%d%dx%d (ratio=%s)", actual_w, actual_h, tw, th, aspect_ratio)
# --- Step2: resample_strength 削像素水印(可选,默认轻采样---
img = _apply_resample(img, resample_strength)
# --- Step2+3: 去AI化破水印硬路默认开倩倩姐2026-06-26拍板对齐大卫xhs实测版---
# 硬路 = 缩2px裁1px边错位采样 + 亮度/饱和微调,专破 SynthID 像素水印。
# 「像素不能有任何压缩」红线大卫硬路只动边缘2px没有全图来回缩放
# Clover 原 Step2缩98%再放大)是额外的全图 LANCZOS 重采样、会软化全图像素,
# 故硬路开启时直接跳过 Step2只走硬路局部错位——既破水印又不压全图像素。
hard_mode = os.environ.get("SYNTHID_HARD_MODE", "1") != "0"
if hard_mode:
# 硬路只动边缘(缩2px裁1px),用图片当前尺寸即可,不依赖 RATIO_MAP
# 故非标准比例(target=None)也走硬路,绝不降级到全图 LANCZOS 有损重采样。
img = _apply_synthid_break(img)
else:
# 仅硬路显式关闭时,才用全图轻采样兜底破水印
img = _apply_resample(img, resample_strength)
# --- Step3: SynthID 破除SYNTHID_HARD_MODE=1 才开,默认关---
if os.environ.get("SYNTHID_HARD_MODE") == "1" and target:
img = _apply_synthid_break(img, target)
# --- Step3.5: 北哥暖棕调色BEIGE_COLOR_GRADE 默认开去AI化核心---
# 在重编码前以 bytes 往返grade 内部自带开关/降级,关则原样透传
if _beige_enabled():
buf0 = io.BytesIO()
img.save(buf0, format="JPEG", quality=100, subsampling=0)
graded = _beige_grade(buf0.getvalue())
img = Image.open(io.BytesIO(graded)).convert("RGB")
# --- Step4: 高保真 JPEG 重编码,去所有元数据 ---
buf = io.BytesIO()
@@ -118,19 +136,20 @@ def _apply_resample(img: "Image.Image", strength: int) -> "Image.Image":
return img
def _apply_synthid_break(img: "Image.Image", target: tuple[int, int]) -> "Image.Image":
def _apply_synthid_break(img: "Image.Image") -> "Image.Image":
"""
SynthID 破除(SYNTHID_HARD_MODE=1 时调用):
对齐大卫逻辑 — 缩到(w-2,h-2)再裁掉1px边 + 亮度*1.005/饱和*0.998
SynthID 破除(硬路,默认开):对齐大卫 xhs 实测版。
顺序对齐大卫:先微调亮度/饱和(modulate) → 再缩2px裁1px边错位采样
只动边缘像素、按图片当前尺寸算,不依赖目标比例,不做全图重采样、不压全图像素。
诚实声明:只能削弱 SynthID不保证 100% 清除。
"""
tw, th = target
img = ImageOps.fit(img, (tw - 2, th - 2), method=Image.LANCZOS)
# 裁掉1px边消除边缘水印残留
img = img.crop((1, 1, tw - 3, th - 3))
# 微调亮度/饱和(对齐大卫 modulate brightness/saturation
# 先 modulate亮度*1.005/饱和*0.998),对齐大卫 modulate 在缩裁之前
img = ImageEnhance.Brightness(img).enhance(1.005)
img = ImageEnhance.Color(img).enhance(0.998)
# 按当前尺寸缩2px再裁1px边错位采样破边缘水印残留w-4 × h-4
w, h = img.size
img = ImageOps.fit(img, (w - 2, h - 2), method=Image.LANCZOS)
img = img.crop((1, 1, w - 3, h - 3))
return img