Add linked mini program functionality and enhance link tag handling
- Introduced `navigateToMiniProgramAppIdList` in app.json for mini program navigation. - Updated link tag handling in the read page to support mini program keys and app IDs. - Enhanced content parsing to include app ID and mini program key in link tags. - Added linked mini programs management in the admin panel with API endpoints for CRUD operations. - Improved UI for selecting linked mini programs in the content creation page.
This commit is contained in:
@@ -57,6 +57,7 @@
|
||||
]
|
||||
},
|
||||
"usingComponents": {},
|
||||
"navigateToMiniProgramAppIdList": [],
|
||||
"__usePrivacyCheck__": true,
|
||||
"lazyCodeLoading": "requiredComponents",
|
||||
"style": "v2",
|
||||
|
||||
@@ -78,11 +78,12 @@ Page({
|
||||
async onLoad(options) {
|
||||
wx.showShareMenu({ withShareTimeline: true })
|
||||
|
||||
// 预加载 linkTags 配置(供 onLinkTagTap 旧格式降级匹配 type 用)
|
||||
if (!app.globalData.linkTagsConfig) {
|
||||
// 预加载 linkTags、linkedMiniprograms(供 onLinkTagTap 用密钥查 appId)
|
||||
if (!app.globalData.linkTagsConfig || !app.globalData.linkedMiniprograms) {
|
||||
app.request({ url: '/api/miniprogram/config', silent: true }).then(cfg => {
|
||||
if (cfg && Array.isArray(cfg.linkTags)) {
|
||||
app.globalData.linkTagsConfig = cfg.linkTags
|
||||
if (cfg) {
|
||||
if (Array.isArray(cfg.linkTags)) app.globalData.linkTagsConfig = cfg.linkTags
|
||||
if (Array.isArray(cfg.linkedMiniprograms)) app.globalData.linkedMiniprograms = cfg.linkedMiniprograms
|
||||
}
|
||||
}).catch(() => {})
|
||||
}
|
||||
@@ -469,12 +470,13 @@ Page({
|
||||
getApp().goBackOrToHome()
|
||||
},
|
||||
|
||||
// 点击正文中的 #链接标签:小程序内页/预览页跳转
|
||||
// 点击正文中的 #链接标签:小程序内页/预览页/唤醒其他小程序
|
||||
onLinkTagTap(e) {
|
||||
let url = (e.currentTarget.dataset.url || '').trim()
|
||||
const label = (e.currentTarget.dataset.label || '').trim()
|
||||
let tagType = (e.currentTarget.dataset.tagType || '').trim()
|
||||
let pagePath = (e.currentTarget.dataset.pagePath || '').trim()
|
||||
let mpKey = (e.currentTarget.dataset.mpKey || '').trim() || (e.currentTarget.dataset.appId || '').trim()
|
||||
|
||||
// 旧格式(<a href>)tagType 为空 → 按 label 从缓存 linkTags 补充类型信息
|
||||
if (!tagType && label) {
|
||||
@@ -483,6 +485,7 @@ Page({
|
||||
tagType = cached.type || 'url'
|
||||
pagePath = cached.pagePath || ''
|
||||
if (!url) url = cached.url || ''
|
||||
if (cached.mpKey) mpKey = cached.mpKey
|
||||
}
|
||||
}
|
||||
|
||||
@@ -493,6 +496,28 @@ Page({
|
||||
return
|
||||
}
|
||||
|
||||
// 小程序类型:用密钥查 linkedMiniprograms 得 appId,再唤醒(需在 app.json 的 navigateToMiniProgramAppIdList 中配置)
|
||||
if (tagType === 'miniprogram') {
|
||||
if (!mpKey && label) {
|
||||
const cached = (app.globalData.linkTagsConfig || []).find(t => t.label === label)
|
||||
if (cached) mpKey = cached.mpKey || cached.appId || ''
|
||||
}
|
||||
const linked = (app.globalData.linkedMiniprograms || []).find(m => (m.key || m.id) === mpKey)
|
||||
if (linked && linked.appId) {
|
||||
wx.navigateToMiniProgram({
|
||||
appId: linked.appId,
|
||||
path: pagePath || linked.path || '',
|
||||
envVersion: 'release',
|
||||
success: () => {},
|
||||
fail: (err) => {
|
||||
wx.showToast({ title: err.errMsg || '跳转失败', icon: 'none' })
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
if (mpKey) wx.showToast({ title: '未找到关联小程序配置', icon: 'none' })
|
||||
}
|
||||
|
||||
// 小程序内部路径(pagePath 或 url 以 /pages/ 开头)
|
||||
const internalPath = pagePath || (url.startsWith('/pages/') ? url : '')
|
||||
if (internalPath) {
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
<block wx:for="{{item}}" wx:key="index" wx:for-item="seg">
|
||||
<text wx:if="{{seg.type === 'text'}}">{{seg.text}}</text>
|
||||
<text wx:elif="{{seg.type === 'mention'}}" class="mention" bindtap="onMentionTap" data-user-id="{{seg.userId}}" data-nickname="{{seg.nickname}}">@{{seg.nickname}}</text>
|
||||
<text wx:elif="{{seg.type === 'linkTag'}}" class="link-tag" bindtap="onLinkTagTap" data-url="{{seg.url}}" data-label="{{seg.label}}" data-tag-type="{{seg.tagType}}" data-page-path="{{seg.pagePath}}" data-tag-id="{{seg.tagId}}">#{{seg.label}}</text>
|
||||
<text wx:elif="{{seg.type === 'linkTag'}}" class="link-tag" bindtap="onLinkTagTap" data-url="{{seg.url}}" data-label="{{seg.label}}" data-tag-type="{{seg.tagType}}" data-page-path="{{seg.pagePath}}" data-tag-id="{{seg.tagId}}" data-app-id="{{seg.appId}}" data-mp-key="{{seg.mpKey}}">#{{seg.label}}</text>
|
||||
<image wx:elif="{{seg.type === 'image'}}" class="content-image" src="{{seg.src}}" mode="widthFix" show-menu-by-longpress bindtap="onImageTap" data-src="{{seg.src}}"></image>
|
||||
</block>
|
||||
</view>
|
||||
|
||||
@@ -23,12 +23,19 @@
|
||||
"condition": {
|
||||
"miniprogram": {
|
||||
"list": [
|
||||
{
|
||||
"name": "唤醒",
|
||||
"pathName": "pages/read/read",
|
||||
"query": "mid=209",
|
||||
"scene": null,
|
||||
"launchMode": "default"
|
||||
},
|
||||
{
|
||||
"name": "pages/my/my",
|
||||
"pathName": "pages/my/my",
|
||||
"query": "",
|
||||
"scene": null,
|
||||
"launchMode": "singlePage"
|
||||
"launchMode": "singlePage",
|
||||
"scene": null
|
||||
},
|
||||
{
|
||||
"name": "pages/read/read",
|
||||
|
||||
@@ -55,17 +55,21 @@ function parseBlockToSegments(block) {
|
||||
if (userId || nickname) segs.push({ type: 'mention', userId, nickname })
|
||||
|
||||
} else if (/data-type="linkTag"/i.test(tag)) {
|
||||
// #linkTag — 自定义 span 格式(data-type="linkTag" data-url="..." data-tag-type="..." data-page-path="...")
|
||||
// #linkTag — 自定义 span 格式(data-type="linkTag" data-url="..." data-tag-type="..." data-page-path="..." data-app-id="...")
|
||||
const urlMatch = tag.match(/data-url="([^"]*)"/)
|
||||
const tagTypeMatch = tag.match(/data-tag-type="([^"]*)"/)
|
||||
const pagePathMatch = tag.match(/data-page-path="([^"]*)"/)
|
||||
const tagIdMatch = tag.match(/data-tag-id="([^"]*)"/)
|
||||
const appIdMatch = tag.match(/data-app-id="([^"]*)"/)
|
||||
const mpKeyMatch = tag.match(/data-mp-key="([^"]*)"/)
|
||||
const innerText = tag.replace(/<[^>]+>/g, '').replace(/^#/, '').trim()
|
||||
const url = urlMatch ? urlMatch[1] : ''
|
||||
const tagType = tagTypeMatch ? tagTypeMatch[1] : 'url'
|
||||
const pagePath = pagePathMatch ? pagePathMatch[1] : ''
|
||||
const tagId = tagIdMatch ? tagIdMatch[1] : ''
|
||||
segs.push({ type: 'linkTag', label: innerText || '#', url, tagType, pagePath, tagId })
|
||||
const appId = appIdMatch ? appIdMatch[1] : ''
|
||||
const mpKey = mpKeyMatch ? mpKeyMatch[1] : (tagType === 'miniprogram' ? appId : '')
|
||||
segs.push({ type: 'linkTag', label: innerText || '#', url, tagType, pagePath, tagId, appId, mpKey })
|
||||
|
||||
} else if (/^<a /i.test(tag)) {
|
||||
// #linkTag — 旧格式 <a href>(insertLinkTag 旧版产生,url 可能为空)
|
||||
|
||||
Reference in New Issue
Block a user