feat: 2026-07-11 全量更新 - 代办集成+会议室预定+知识迭代修复+UI统一+Bug修复
== 已部署上线 (9项) == - 代办事项真实数据源集成 (企微审批API 8bug修复链) - H5/坐席端 Logo样式统一+绿色背景 - 视频引导页修复 (localStorage key v2) - 坐席端 v9 Vue版本修复 (ElMessage._context) - 截图按钮 v10 修复 (getDisplayMedia user gesture) - 扫码样式恢复+H5扫码登录跳转修复 - H5截图快捷键提示 == 代码完成待部署 (3项) == - 知识迭代3Bug修复 (#8 POST端点/#7 MERGE幂等/#6 过期检查) - 会议室预定-小鱼易联终端 (40文件, 40/40测试通过) - IT资产升级审批推送 (asset_service.py) == 需求文档 (2项) == - 坐席端AI辅助消息框-PRD (4项新功能确认) - 坐席端布局优化建议 v2.0 (7天计划) == 新增文档 == - 日报-2026-07-11.md - 知识迭代Bug修复报告-20260711.md - 会议室预定-部署指南.md - CHANGELOG.md 更新 == 测试 == - test_todo_integration.py: 40/40 - test_meetingroom.py: 40/40 - test_bugfix_ki_suggestions.py: 21/21
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
#!/usr/bin/env python3
|
||||
"""生成精美通知卡片"""
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
from io import BytesIO
|
||||
|
||||
def create_card():
|
||||
W, H = 600, 320
|
||||
|
||||
# 创建画布
|
||||
img = Image.new('RGBA', (W, H), (0, 0, 0, 0))
|
||||
draw = ImageDraw.Draw(img)
|
||||
|
||||
# ==================== 卡片背景 ====================
|
||||
# 主背景 - 柔和蓝渐变
|
||||
for y in range(H):
|
||||
ratio = y / H
|
||||
r = int(30 + (60 - 30) * ratio)
|
||||
g = int(100 + (160 - 100) * ratio)
|
||||
b = int(200 + (220 - 200) * ratio)
|
||||
draw.line([(0, y), (W, y)], fill=(r, g, b, 255))
|
||||
|
||||
# 卡片主体圆角
|
||||
card_x, card_y = 10, 10
|
||||
card_w, card_h = W - 20, H - 20
|
||||
|
||||
# 绘制圆角矩形作为底板
|
||||
draw.rounded_rectangle(
|
||||
[card_x, card_y, card_x + card_w, card_y + card_h],
|
||||
radius=20, fill=(255, 255, 255, 240)
|
||||
)
|
||||
|
||||
# ==================== 顶部装饰 ====================
|
||||
# 装饰线条
|
||||
draw.line([(card_x + 20, card_y + 20), (card_x + card_w - 20, card_y + 20)], fill=(7, 193, 96, 200), width=3)
|
||||
|
||||
# ==================== 图标区域 ====================
|
||||
# 时钟图标(圆形背景)
|
||||
icon_x, icon_y = 60, 70
|
||||
draw.ellipse([icon_x - 25, icon_y - 25, icon_x + 25, icon_y + 25], fill=(7, 193, 96, 30))
|
||||
draw.ellipse([icon_x - 20, icon_y - 20, icon_x + 20, icon_y + 20], outline=(7, 193, 96, 255), width=2)
|
||||
|
||||
# 时针
|
||||
draw.line([icon_x, icon_y, icon_x, icon_y - 10], fill=(7, 193, 96, 255), width=2)
|
||||
# 分针
|
||||
draw.line([icon_x, icon_y, icon_x + 8, icon_y + 5], fill=(7, 193, 96, 255), width=2)
|
||||
# 中心点
|
||||
draw.ellipse([icon_x - 2, icon_y - 2, icon_x + 2, icon_y + 2], fill=(7, 193, 96, 255))
|
||||
|
||||
# ==================== 标题文字 ====================
|
||||
try:
|
||||
title_font = ImageFont.truetype("C:/Windows/Fonts/msyh.ttc", 28)
|
||||
subtitle_font = ImageFont.truetype("C:/Windows/Fonts/msyh.ttc", 16)
|
||||
btn_font = ImageFont.truetype("C:/Windows/Fonts/msyh.ttc", 20)
|
||||
except:
|
||||
try:
|
||||
title_font = ImageFont.truetype("C:/Windows/Fonts/simhei.ttf", 28)
|
||||
subtitle_font = ImageFont.truetype("C:/Windows/Fonts/simhei.ttf", 16)
|
||||
btn_font = ImageFont.truetype("C:/Windows/Fonts/simhei.ttf", 20)
|
||||
except:
|
||||
title_font = ImageFont.load_default()
|
||||
subtitle_font = ImageFont.load_default()
|
||||
btn_font = ImageFont.load_default()
|
||||
|
||||
# 主标题
|
||||
title = "IT咨询即将关闭"
|
||||
draw.text((100, 55), title, fill=(40, 40, 40), font=title_font)
|
||||
|
||||
# 副标题
|
||||
subtitle = "请尽快回复坐席,否则咨询将自动结束"
|
||||
draw.text((100, 95), subtitle, fill=(120, 120, 120), font=subtitle_font)
|
||||
|
||||
# ==================== 3D水晶按钮 ====================
|
||||
btn_x, btn_y = 40, 150
|
||||
btn_w, btn_h = 520, 60
|
||||
btn_radius = 15
|
||||
|
||||
# 按钮阴影
|
||||
draw.rounded_rectangle(
|
||||
[btn_x + 4, btn_y + 4, btn_x + btn_w + 4, btn_y + btn_h + 4],
|
||||
radius=btn_radius, fill=(0, 0, 0, 40)
|
||||
)
|
||||
|
||||
# 按钮主体 - 渐变
|
||||
for i in range(btn_h):
|
||||
ratio = i / btn_h
|
||||
# 绿色渐变
|
||||
r = int(7 + (20 - 7) * ratio)
|
||||
g = int(193 + (180 - 193) * ratio)
|
||||
b = int(96 + (60 - 96) * ratio)
|
||||
draw.rectangle([btn_x, btn_y + i, btn_x + btn_w, btn_y + i + 1], fill=(r, g, b))
|
||||
|
||||
# 按钮顶部高光
|
||||
draw.rounded_rectangle(
|
||||
[btn_x, btn_y, btn_x + btn_w, btn_y + btn_h // 2],
|
||||
radius=btn_radius, fill=(255, 255, 255, 40)
|
||||
)
|
||||
|
||||
# 按钮边框
|
||||
draw.rounded_rectangle(
|
||||
[btn_x, btn_y, btn_x + btn_w, btn_y + btn_h],
|
||||
radius=btn_radius, outline=(5, 150, 70, 100), width=1
|
||||
)
|
||||
|
||||
# 按钮文字
|
||||
btn_text = "立即回复"
|
||||
# 计算文字居中
|
||||
bbox = draw.textbbox((0, 0), btn_text, font=btn_font)
|
||||
text_w = bbox[2] - bbox[0]
|
||||
text_x = btn_x + (btn_w - text_w) // 2
|
||||
text_y = btn_y + (btn_h - (bbox[3] - bbox[1])) // 2 - 2
|
||||
draw.text((text_x, text_y), btn_text, fill=(255, 255, 255), font=btn_font)
|
||||
|
||||
# ==================== 底部提示 ====================
|
||||
tip = "点击卡片直接跳转到咨询页面"
|
||||
draw.text((card_x + 20, card_y + card_h - 30), tip, fill=(150, 150, 150), font=subtitle_font)
|
||||
|
||||
# 保存
|
||||
buffer = BytesIO()
|
||||
img.save(buffer, format='PNG')
|
||||
buffer.seek(0)
|
||||
return buffer.getvalue()
|
||||
|
||||
|
||||
# 本地测试
|
||||
if __name__ == "__main__":
|
||||
data = create_card()
|
||||
with open("D:/资料/03-项目开发/wecom_it_smart_desk/deploy-server/it_reminder_card_v2.png", "wb") as f:
|
||||
f.write(data)
|
||||
print("✅ 卡片已保存")
|
||||
Reference in New Issue
Block a user