This commit is contained in:
Alex-larget
2026-03-24 18:45:32 +08:00
parent dcb7961945
commit f3d74ce94a
68 changed files with 2461 additions and 2535 deletions

View File

@@ -54,8 +54,14 @@ function stripTrailingAtForMention(before) {
* 将一个 HTML block 字符串解析为 segments 数组
* 处理三种内联元素mention / linkTag(span) / linkTag(a) / img
*/
function parseBlockToSegments(block) {
function parseBlockToSegments(block, config) {
const segs = []
const normalize = s => (s || '').trim().toLowerCase()
const personTokenSet = new Set()
for (const p of ((config && config.persons) || [])) {
const token = normalize((p && p.token) || '')
if (token) personTokenSet.add(token)
}
// 合并匹配所有内联元素
const tokenRe = /<span[^>]*data-type="mention"[^>]*>[\s\S]*?<\/span>|<span[^>]*data-type="linkTag"[^>]*>[\s\S]*?<\/span>|<a[^>]*href="([^"]*)"[^>]*>(#[^<]*)<\/a>|<img[^>]*\/?>/gi
let lastEnd = 0
@@ -78,8 +84,12 @@ function parseBlockToSegments(block) {
const userId = idMatch ? idMatch[1].trim() : ''
let nickname = labelMatch ? labelMatch[1] : innerText.replace(/^[@]\s*/, '')
nickname = cleanMentionNickname((nickname || '').trim())
if (userId || nickname) {
const userExists = !!normalize(userId) && personTokenSet.has(normalize(userId))
if (userExists && nickname) {
segs.push({ type: 'mention', userId, nickname, mentionDisplay: '@' + nickname })
} else if (nickname) {
// 被 @ 人物不存在时降级为普通文本,保持“静态 @某人”展示
segs.push({ type: 'text', text: '@' + nickname })
}
} else if (/data-type="linkTag"/i.test(tag)) {
@@ -155,7 +165,7 @@ function parseHtmlToSegments(html, config) {
for (const block of blocks) {
if (!block.trim()) continue
let blockSegs = parseBlockToSegments(block)
let blockSegs = parseBlockToSegments(block, config)
if (!blockSegs.length) continue
// 纯图片行独立成段

View File

@@ -59,16 +59,20 @@ function syncOrderStatusQuery(app, orderSn) {
/**
* 提交存客宝 lead与阅读页 @、会员详情点头像同接口)
* @param {object} app getApp()
* @param {{ targetUserId: string, targetNickname?: string, source: string, phoneModalContent?: string }} opts
* @param {{ targetUserId?: string, targetNickname?: string, targetMemberId?: string, targetMemberName?: string, source: string, phoneModalContent?: string }} opts
* @returns {Promise<boolean>} 是否提交成功
*/
async function submitCkbLead(app, opts) {
const targetUserId = (opts && opts.targetUserId) || ''
const targetNickname = ((opts && opts.targetNickname) || 'TA').trim() || 'TA'
const targetUserId = ((opts && opts.targetUserId) || '').trim()
const targetMemberId = ((opts && opts.targetMemberId) || '').trim()
let targetNickname = (opts && opts.targetNickname != null) ? String(opts.targetNickname).trim() : ''
if (targetUserId && !targetNickname) targetNickname = 'TA'
const targetMemberName = ((opts && opts.targetMemberName) || '').trim()
const source = (opts && opts.source) || 'article_mention'
const phoneModalContent = (opts && opts.phoneModalContent) || '请先填写手机号(必填),以便对方联系您'
if (!targetUserId) return false
// 文章 @ 为 token会员详情无 token 时用 targetMemberId 走全局获客计划(与后端 CKBLead 一致)
if (!targetUserId && !targetMemberId) return false
if (!app.globalData.isLoggedIn || !app.globalData.userInfo) {
return await new Promise((resolve) => {
@@ -124,8 +128,10 @@ async function submitCkbLead(app, opts) {
phone: phone || undefined,
wechatId: wechatId || undefined,
name: (app.globalData.userInfo.nickname || '').trim() || undefined,
targetUserId,
targetNickname: targetNickname || undefined,
targetUserId: targetUserId || undefined,
targetNickname: targetNickname !== '' ? targetNickname : undefined,
targetMemberId: targetMemberId || undefined,
targetMemberName: targetMemberName || undefined,
source
}
})
@@ -141,7 +147,9 @@ async function submitCkbLead(app, opts) {
return false
} catch (e) {
wx.hideLoading()
wx.showToast({ title: (e && e.message) || '提交失败', icon: 'none' })
const resp = e && e.response
const hint = (resp && (resp.message || resp.error)) || (e && e.message) || '提交失败'
wx.showToast({ title: String(hint), icon: 'none' })
return false
}
}