Files
inquiry_robot/inquiry-agent/agent/channel/h5/copy_page.py
T

151 lines
4.8 KiB
Python

"""
复制工单号页 HTML。
本文件职责:打开后立刻把工单号写入系统剪贴板(企微 JS-SDK + 浏览器兜底)。
禁止:URL/页面带 userid;禁止在本页调主账或改六态。
"""
from __future__ import annotations
import html
from agent.config import get_settings
_EXPIRED_HTML = """<!doctype html>
<html lang="zh-CN"><head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1"/>
<title>链接已过期</title>
</head><body style="font-family:sans-serif;padding:32px;text-align:center;color:#333">
<p>复制链接已过期。</p>
<p>请回到企微,重新询价后再点「复制工单号」。</p>
</body></html>
"""
def expired_copy_page() -> str:
"""token 无效时给销售看的短页,不暴露内部原因。"""
return _EXPIRED_HTML
def render_copy_page(work_order_no: str) -> str:
"""
渲染复制页。工单号只进页面正文,由 JS 写入剪贴板。
先走企微 ww.setClipboardData(应用内才能真复制),失败再走浏览器剪贴板。
"""
wo = html.escape((work_order_no or "").strip(), quote=True)
settings = get_settings()
corp = html.escape((settings.wecom_corp_id or "").strip(), quote=True)
agent = html.escape(str(settings.wecom_agent_id or "1000010").strip(), quote=True)
return f"""<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1"/>
<title>复制工单号</title>
<style>
body {{ margin:0; font-family:-apple-system,BlinkMacSystemFont,"PingFang SC","Microsoft YaHei",sans-serif;
background:#f5f6f7; color:#1f2329; }}
.wrap {{ max-width:420px; margin:48px auto; padding:0 20px; text-align:center; }}
.wo {{ font-size:22px; font-weight:600; letter-spacing:.04em; margin:16px 0 8px; word-break:break-all; }}
.st {{ min-height:24px; color:#646a73; font-size:14px; }}
.ok {{ color:#00a870; }}
.bad {{ color:#d83931; }}
button {{ margin-top:20px; width:100%; height:44px; border:0; border-radius:8px;
background:#1677ff; color:#fff; font-size:16px; }}
</style>
</head>
<body>
<div class="wrap">
<div>工单号</div>
<div class="wo" id="wo" data-wo="{wo}">{wo}</div>
<div class="st" id="st">正在复制…</div>
<button type="button" id="btn">复制工单号</button>
</div>
<script src="https://wwcdn.weixin.qq.com/node/wework/open/js/wecom-jssdk-2.3.2.js"></script>
<script>
(function () {{
var text = document.getElementById("wo").getAttribute("data-wo") || "";
var st = document.getElementById("st");
var corpId = "{corp}";
var agentId = Number("{agent}") || 0;
function show(ok, msg) {{
st.className = "st " + (ok ? "ok" : "bad");
st.textContent = msg;
}}
function browserCopy(value) {{
if (navigator.clipboard && navigator.clipboard.writeText) {{
return navigator.clipboard.writeText(value);
}}
return new Promise(function (resolve, reject) {{
var box = document.createElement("textarea");
box.value = value;
box.setAttribute("readonly", "readonly");
box.style.position = "fixed";
box.style.left = "-9999px";
document.body.appendChild(box);
box.select();
try {{
if (!document.execCommand("copy")) throw new Error("exec");
resolve();
}} catch (err) {{ reject(err); }}
document.body.removeChild(box);
}});
}}
function wecomCopy(value) {{
if (window.ww && ww.setClipboardData) {{
return ww.setClipboardData({{ data: value }});
}}
return Promise.reject(new Error("no-ww"));
}}
function sign(kind) {{
return function (url) {{
return fetch("/inquiry-form/jsapi-signature?kind=" + encodeURIComponent(kind)
+ "&url=" + encodeURIComponent(url))
.then(function (r) {{
if (!r.ok) throw new Error("sign");
return r.json();
}});
}};
}}
function tryCopy() {{
return wecomCopy(text).catch(function () {{ return browserCopy(text); }})
.then(function () {{ show(true, "已复制到剪贴板"); }})
.catch(function () {{ show(false, "复制失败,请再点一次按钮"); }});
}}
function boot() {{
var ready = Promise.resolve();
if (window.ww && ww.register && corpId) {{
ready = ww.register({{
corpId: corpId,
agentId: agentId,
jsApiList: ["setClipboardData"],
getConfigSignature: sign("corp"),
getAgentConfigSignature: sign("agent")
}}).catch(function () {{ return null; }});
}}
ready.then(tryCopy).catch(tryCopy);
}}
document.getElementById("btn").addEventListener("click", function () {{
show(true, "正在复制…");
tryCopy();
}});
if (document.readyState === "loading") {{
document.addEventListener("DOMContentLoaded", boot);
}} else {{
boot();
}}
}})();
</script>
</body>
</html>
"""