chore(brand): 统一将品牌名从雄戈小酒更改为橙虎小酒 - 更新alisms插件配置中的签名值 - 修改shopro插件中所有SQL脚本的品牌名称引用 - 更新商城配置、商品分类、演示数据中的品牌名称 - 替换后台登录页面的品牌标识 - 更新汇付分账配置中的媒介名称 - 修改登录预览生成脚本中的品牌显示 ```
185 行
8.3 KiB
Python
185 行
8.3 KiB
Python
"""Generate admin login page preview mockups for 橙虎小酒."""
|
||
from pathlib import Path
|
||
from PIL import Image, ImageDraw, ImageFont
|
||
|
||
ROOT = Path(__file__).resolve().parent
|
||
OUT = ROOT / "previews"
|
||
OUT.mkdir(exist_ok=True)
|
||
W, H = 1440, 900
|
||
|
||
|
||
def load_font(size: int, bold: bool = False):
|
||
for path in (
|
||
r"C:\Windows\Fonts\msyhbd.ttc" if bold else r"C:\Windows\Fonts\msyh.ttc",
|
||
r"C:\Windows\Fonts\simhei.ttf",
|
||
):
|
||
if Path(path).exists():
|
||
return ImageFont.truetype(path, size)
|
||
return ImageFont.load_default()
|
||
|
||
|
||
def vertical_gradient(size, top, bottom):
|
||
w, h = size
|
||
img = Image.new("RGB", size, top)
|
||
draw = ImageDraw.Draw(img)
|
||
for y in range(h):
|
||
t = y / max(h - 1, 1)
|
||
r = int(top[0] + (bottom[0] - top[0]) * t)
|
||
g = int(top[1] + (bottom[1] - top[1]) * t)
|
||
b = int(top[2] + (bottom[2] - top[2]) * t)
|
||
draw.line([(0, y), (w, y)], fill=(r, g, b))
|
||
return img
|
||
|
||
|
||
def draw_badge(draw, cx, cy, r, text, gold=True):
|
||
draw.ellipse((cx - r, cy - r, cx + r, cy + r), fill=(18, 55, 120))
|
||
if gold:
|
||
draw.ellipse((cx - r, cy - r, cx + r, cy + r), outline=(201, 162, 39), width=3)
|
||
font = load_font(int(r * 0.55), bold=True)
|
||
draw.text((cx, cy), text, fill=(245, 215, 142), font=font, anchor="mm")
|
||
|
||
|
||
def draw_login_card(draw, x, y, w, h, shadow=True):
|
||
if shadow:
|
||
draw.rounded_rectangle((x + 6, y + 8, x + w + 6, y + h + 8), radius=16, fill=(0, 0, 0, 30))
|
||
draw.rounded_rectangle((x, y, x + w, y + h), radius=16, fill=(255, 255, 255))
|
||
draw.rounded_rectangle((x, y, x + w, y + h), radius=16, outline=(229, 231, 235), width=1)
|
||
|
||
|
||
def draw_form_fields(draw, x, y, w):
|
||
title_f = load_font(28, bold=True)
|
||
sub_f = load_font(15)
|
||
label_f = load_font(13, bold=True)
|
||
draw.text((x, y), "欢迎登录", fill=(31, 41, 55), font=title_f)
|
||
draw.text((x, y + 42), "请使用管理员账号登录后台", fill=(107, 114, 128), font=sub_f)
|
||
fy = y + 88
|
||
for label in ("用户名", "密码"):
|
||
draw.text((x, fy), label, fill=(31, 41, 55), font=label_f)
|
||
draw.rounded_rectangle((x, fy + 24, x + w, fy + 64), radius=8, fill=(250, 251, 252), outline=(229, 231, 235))
|
||
fy += 88
|
||
draw.rounded_rectangle((x, fy + 8, x + 22, fy + 28), radius=4, fill=(22, 119, 255))
|
||
draw.text((x + 32, fy + 6), "保持会话(24小时内免重复登录)", fill=(107, 114, 128), font=sub_f)
|
||
draw.rounded_rectangle((x, fy + 44, x + w, fy + 92), radius=8, fill=(22, 119, 255))
|
||
draw.text((x + w // 2, fy + 68), "登 录 后 台", fill=(255, 255, 255), font=load_font(16, bold=True), anchor="mm")
|
||
|
||
|
||
def draw_bottle_icon(draw, cx, cy, scale=1.0):
|
||
s = scale
|
||
draw.ellipse((cx - 40 * s, cy + 90 * s, cx + 40 * s, cy + 110 * s), fill=(0, 0, 0, 40))
|
||
draw.rounded_rectangle((cx - 28 * s, cy - 70 * s, cx + 28 * s, cy + 90 * s), radius=int(12 * s), fill=(22, 119, 255))
|
||
draw.rounded_rectangle((cx - 24 * s, cy - 90 * s, cx + 24 * s, cy - 68 * s), radius=int(6 * s), fill=(9, 88, 217))
|
||
draw.rounded_rectangle((cx - 18 * s, cy - 108 * s, cx + 18 * s, cy - 88 * s), radius=int(4 * s), fill=(201, 162, 39))
|
||
draw.rounded_rectangle((cx - 20 * s, cy + 10 * s, cx + 20 * s, cy + 50 * s), radius=int(4 * s), fill=(255, 255, 255, 40))
|
||
draw.text((cx, cy + 32 * s), "雄", fill=(255, 255, 255), font=load_font(int(22 * s), bold=True), anchor="mm")
|
||
|
||
|
||
def scheme_a_split(img):
|
||
"""方案A:左深蓝品牌区 + 右白卡片(推荐)"""
|
||
draw = ImageDraw.Draw(img)
|
||
split = int(W * 0.58)
|
||
left = vertical_gradient((split, H), (10, 36, 99), (18, 55, 120))
|
||
img.paste(left, (0, 0))
|
||
right = Image.new("RGB", (W - split, H), (245, 247, 250))
|
||
img.paste(right, (split, 0))
|
||
|
||
draw = ImageDraw.Draw(img)
|
||
draw_badge(draw, 120, 120, 48, "雄戈")
|
||
draw.text((120, 190), "橙虎小酒", fill=(255, 255, 255), font=load_font(42, bold=True))
|
||
draw.text((120, 250), "商城运营管理中心", fill=(180, 200, 230), font=load_font(18))
|
||
draw.text((120, 282), "商品 · 订单 · 分销 · 区域服务", fill=(140, 170, 210), font=load_font(15))
|
||
draw_bottle_icon(draw, 360, 480, 2.2)
|
||
|
||
for i, (t, d) in enumerate([("商城", "商品订单"), ("分销", "佣金团队"), ("区域", "服务商")]):
|
||
bx = 120 + i * 150
|
||
draw.text((bx, 720), t, fill=(64, 150, 255), font=load_font(22, bold=True))
|
||
draw.text((bx, 752), d, fill=(140, 170, 210), font=load_font(13))
|
||
|
||
cw, ch = 380, 460
|
||
cx = split + (W - split - cw) // 2
|
||
cy = (H - ch) // 2
|
||
draw_login_card(draw, cx, cy, cw, ch)
|
||
draw_form_fields(draw, cx + 36, cy + 36, cw - 72)
|
||
|
||
banner = load_font(14, bold=True)
|
||
draw.rectangle((0, H - 36, W, H), fill=(22, 119, 255))
|
||
draw.text((W // 2, H - 18), "方案 A · 左右分栏 · 商务蓝白(推荐)", fill=(255, 255, 255), font=banner, anchor="mm")
|
||
return img
|
||
|
||
|
||
def scheme_b_centered(img):
|
||
"""方案B:全屏渐变 + 居中卡片"""
|
||
img = vertical_gradient((W, H), (10, 36, 99), (22, 119, 255))
|
||
draw = ImageDraw.Draw(img)
|
||
for cx, cy, r in ((200, 200, 180), (1200, 700, 220), (900, 150, 120)):
|
||
overlay = Image.new("RGBA", (W, H), (0, 0, 0, 0))
|
||
od = ImageDraw.Draw(overlay)
|
||
od.ellipse((cx - r, cy - r, cx + r, cy + r), fill=(64, 150, 255, 25))
|
||
img = Image.alpha_composite(img.convert("RGBA"), overlay).convert("RGB")
|
||
draw = ImageDraw.Draw(img)
|
||
|
||
draw_badge(draw, W // 2, 130, 56, "雄戈")
|
||
draw.text((W // 2, 220), "橙虎小酒 · 后台管理", fill=(255, 255, 255), font=load_font(36, bold=True), anchor="mm")
|
||
draw.text((W // 2, 268), "一男人的朋友一", fill=(200, 220, 255), font=load_font(16), anchor="mm")
|
||
|
||
cw, ch = 420, 480
|
||
cx, cy = (W - cw) // 2, 310
|
||
draw_login_card(draw, cx, cy, cw, ch)
|
||
draw_form_fields(draw, cx + 36, cy + 36, cw - 72)
|
||
|
||
draw.rectangle((0, H - 36, W, H), fill=(9, 88, 217))
|
||
draw.text((W // 2, H - 18), "方案 B · 全屏渐变 · 居中登录卡", fill=(255, 255, 255), font=load_font(14, bold=True), anchor="mm")
|
||
return img
|
||
|
||
|
||
def scheme_c_premium(img):
|
||
"""方案C:深色奢品 + 金色点缀"""
|
||
img = vertical_gradient((W, H), (8, 20, 48), (10, 36, 99))
|
||
draw = ImageDraw.Draw(img)
|
||
split = int(W * 0.55)
|
||
draw.line([(split, 0), (split, H)], fill=(201, 162, 39, 80), width=1)
|
||
|
||
draw_badge(draw, 100, 100, 52, "雄戈")
|
||
draw.text((100, 175), "橙虎小酒", fill=(245, 215, 142), font=load_font(40, bold=True))
|
||
draw.text((100, 232), "XIONGGE LIQUOR ADMIN", fill=(201, 162, 39), font=load_font(14))
|
||
draw.text((100, 270), "高端白酒 · 数字化运营平台", fill=(160, 180, 210), font=load_font(16))
|
||
|
||
draw.rounded_rectangle((80, 340, 520, 760), radius=20, outline=(201, 162, 39), width=2)
|
||
draw_bottle_icon(draw, 300, 520, 2.5)
|
||
|
||
cw, ch = 400, 500
|
||
cx = split + (W - split - cw) // 2
|
||
cy = (H - ch) // 2
|
||
draw.rounded_rectangle((cx, cy, cx + cw, cy + ch), radius=16, fill=(20, 35, 70), outline=(201, 162, 39, 120), width=1)
|
||
title_f = load_font(28, bold=True)
|
||
draw.text((cx + 36, cy + 36), "欢迎登录", fill=(255, 255, 255), font=title_f)
|
||
draw.text((cx + 36, cy + 78), "管理员专用入口", fill=(160, 180, 210), font=load_font(14))
|
||
fy = cy + 120
|
||
for label in ("用户名", "密码"):
|
||
draw.text((cx + 36, fy), label, fill=(200, 210, 230), font=load_font(13, bold=True))
|
||
draw.rounded_rectangle((cx + 36, fy + 24, cx + cw - 36, fy + 64), radius=8, fill=(12, 25, 55), outline=(60, 80, 120))
|
||
fy += 88
|
||
draw.rounded_rectangle((cx + 36, fy + 44, cx + cw - 36, fy + 92), radius=8, fill=(201, 162, 39))
|
||
draw.text((cx + cw // 2, fy + 68), "登 录 后 台", fill=(20, 35, 70), font=load_font(16, bold=True), anchor="mm")
|
||
|
||
draw.rectangle((0, H - 36, W, H), fill=(201, 162, 39))
|
||
draw.text((W // 2, H - 18), "方案 C · 深色奢品 · 金色点缀", fill=(20, 35, 70), font=load_font(14, bold=True), anchor="mm")
|
||
return img
|
||
|
||
|
||
def main():
|
||
schemes = [
|
||
("login-preview-A-split-blue.jpg", scheme_a_split),
|
||
("login-preview-B-center-gradient.jpg", scheme_b_centered),
|
||
("login-preview-C-dark-gold.jpg", scheme_c_premium),
|
||
]
|
||
for name, fn in schemes:
|
||
base = Image.new("RGB", (W, H), (255, 255, 255))
|
||
out = fn(base)
|
||
path = OUT / name
|
||
out.save(path, "JPEG", quality=92)
|
||
print(f"saved {path}")
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|