From c1618d9050e0cc7310c534b2375e90f1961c5a86 Mon Sep 17 00:00:00 2001 From: lbw_9527443 <780139497@qq.com> Date: Wed, 4 Mar 2026 19:32:27 +0800 Subject: [PATCH] =?UTF-8?q?feat(SendPage):=20=E9=87=8D=E6=9E=84=E8=AF=84?= =?UTF-8?q?=E4=BC=B0=E8=A1=A8=E5=8D=95=E9=A1=B5=E9=9D=A2=E5=B9=B6=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E5=A4=9A=E8=A1=A8=E5=8D=95=E7=B1=BB=E5=9E=8B=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 重构发送页面UI,增加背景装饰和卡片式布局。新增支持发送两种不同类型的评估表单(家庭教育档案和入营测评卷),并优化了倒计时和状态管理逻辑。同时改进了企微消息发送功能,根据不同类型显示不同标题和描述。 --- src/components/SendPage.vue | 543 +++++++++++++++++++----------------- 1 file changed, 288 insertions(+), 255 deletions(-) diff --git a/src/components/SendPage.vue b/src/components/SendPage.vue index 500f1be..061d4b2 100644 --- a/src/components/SendPage.vue +++ b/src/components/SendPage.vue @@ -1,29 +1,60 @@ @@ -32,303 +63,305 @@ import { ref, onMounted } from 'vue' import * as ww from '@wecom/jssdk' +// --- 状态定义 --- +type FormType = 'archive' | 'campTest' +const isCoolingDown = ref(false) +const countdown = ref(0) +const activeType = ref(null) const isWWReady = ref(false) -const errorMessage = ref(null) -// --- 防重复点击逻辑 --- -const isCoolingDown = ref(false) // 是否处于冷却期 -const countdown = ref(0) // 倒计时秒数 - -const handleSendForm = () => { - // 如果正在冷却中,直接阻断 - if (isCoolingDown.value) return - - // 启动10秒倒计时 - startCooldown(10) - - // 执行业务逻辑 - GetFormUrl() +// --- 配置表 --- +const CONFIG = { + archive: { + id: 0, + title: '家庭教育档案信息表', + desc: '通过专业的评估工具,了解孩子的成长需求。' + }, + campTest: { + id: 2, + title: '青少年入营测评卷', + desc: '入营前专属专业测评,帮助导师全方位了解营员特质。' + } } -// 倒计时工具函数 -const startCooldown = (seconds: number) => { +// --- 核心逻辑 --- +const handleSend = async (type: FormType) => { + if (isCoolingDown.value) return + + activeType.value = type + startTimer(8) // 8秒冷却 + + try { + // 1. 获取外部联系人ID + const contact = await ww.getCurExternalContact() + const userId = contact.userId + + // 2. 请求后端获取表单URL + const apiUrl = `https://liaison.nycjy.cn/api/v1/archive/form-url?user_id=${userId}&form_id=${CONFIG[type].id}` + const res = await fetch(apiUrl).then(r => r.json()) + + if (res.code === 200 && res.data?.form_url) { + // 3. 调用企微原生接口发送消息卡片 + await ww.sendChatMessage({ + msgtype: 'news', + news: { + title: CONFIG[type].title, + desc: CONFIG[type].desc, + imgUrl: 'https://forms.nycjy.cn/favicon.ico', + link: res.data.form_url + } + }) + } else { + alert('获取链接失败:' + (res.message || '未知错误')) + } + } catch (err) { + console.error('发送流程出错:', err) + } +} + +const startTimer = (seconds: number) => { isCoolingDown.value = true countdown.value = seconds - const timer = setInterval(() => { countdown.value-- if (countdown.value <= 0) { clearInterval(timer) - isCoolingDown.value = false // 倒计时结束,恢复按钮可用 + isCoolingDown.value = false + activeType.value = null } }, 1000) } -// -------------------- -async function getConfigSignature(url: string) { +// --- 初始化企业微信SDK --- +const initSDK = async () => { try { - const response = await fetch('https://sidebar.wx.nycjy.cn/api/v1/wecom/config-signature', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ url }) - }) - if (!response.ok) throw new Error('获取企业签名失败') - return await response.json() - } catch (error) { - console.error('[getConfigSignature]', error) - throw error - } -} + const url = window.location.href.split('#')[0] -async function getAgentConfigSignature(url: string) { - try { - const response = await fetch('https://sidebar.wx.nycjy.cn/api/v1/wecom/agent-config-signature', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ url }) - }) - if (!response.ok) throw new Error('获取应用签名失败') - return await response.json() - } catch (error) { - console.error('[getAgentConfigSignature]', error) - throw error - } -} + // 签名函数 (对应你后端接口) + const getSig = async (apiUrl: string) => { + return await fetch(apiUrl, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ url }) + }).then(r => r.json()) + } -const initWeWork = async () => { - try { await ww.register({ corpId: 'wwf72acc5a681dca93', agentId: 1000105, jsApiList: ['sendChatMessage', 'getCurExternalContact', 'getContext'], - getConfigSignature, - getAgentConfigSignature + getConfigSignature: () => getSig('https://sidebar.wx.nycjy.cn/api/v1/wecom/config-signature'), + getAgentConfigSignature: () => getSig('https://sidebar.wx.nycjy.cn/api/v1/wecom/agent-config-signature') }) isWWReady.value = true - } catch (error) { - isWWReady.value = false - errorMessage.value = '企业微信JS-SDK初始化失败,请刷新页面重试。' + console.log('企微SDK初始化成功') + } catch (e) { + console.error('SDK初始化失败', e) } } -const getUserInfo = async () => { - try { - const response = await ww.getCurExternalContact() - return response.userId - } catch (error) { - console.error('[getCurExternalContact] 失败', error) - throw error - } -} - -const GetFormUrl = async () => { - try { - const userId = await getUserInfo() - const response = await fetch(`https://liaison.nycjy.cn/api/v1/archive/form-url?user_id=${userId}`, { - method: 'GET', - headers: { 'Content-Type': 'application/json' } - }) - - const formUrl = await response.json() - console.log('[GetFormUrl]', formUrl.data) - sendFormLink(formUrl.data.form_url) - if (!response.ok) throw new Error('获取表单URL失败') - } catch (error) { - console.error('[GetFormUrl]', error) - // 如果希望出错时允许立即重试,可以在这里取消冷却: - // isCoolingDown.value = false - alert('请求失败,请检查网络或稍后重试。') - } -} - -const sendFormLink = async (formUrl: string) => { - if (!isWWReady.value) { - alert('企业微信功能尚未准备好,请稍等片刻...') - return - } - try { - await ww.sendChatMessage({ - msgtype: 'news', - news: { - title: '家庭教育档案信息表', - desc: '通过专业的评估工具,了解孩子的成长需求,为每个孩子制定个性化的成长方案', - imgUrl: 'https://forms.nycjy.cn/favicon.ico', - link: formUrl - } - }) - } catch (error) { - console.error('发送消息失败:', error) - alert('发送失败,详情请查看控制台日志。') - } -} - -onMounted(async () => { - await initWeWork() -}) +onMounted(() => initSDK())