feat: enhance link tag functionality with phone parameter support

- Updated link tag structure to include `passPhone` and `phoneParamName` attributes for better integration with user phone data.
- Adjusted related components and database schema to accommodate new attributes.
- Improved documentation and user interface to reflect changes in phone parameter handling during mini program navigation.
This commit is contained in:
Alex-larget
2026-04-07 16:17:16 +08:00
parent 36b8524bc9
commit 3752fc3d9a
3 changed files with 90 additions and 22 deletions

View File

@@ -11,8 +11,8 @@ const DEFAULT_APP_ID = 'wxb8bbb2b10dec74aa'
const DEFAULT_MCH_ID = '1318592501'
const DEFAULT_WITHDRAW_TMPL_ID = 'u3MbZGPRkrZIk-I7QdpwzFxnO_CeQPaCWF2FkiIablE'
// 线上正式域名(真机/体验版/正式版强制使用此地址)
// const API_BASE_URL_PROD = 'https://soulapi.quwanzhi.com'
const API_BASE_URL_PROD = 'https://souldev.quwanzhi.com'
const API_BASE_URL_PROD = 'https://soulapi.quwanzhi.com'
// const API_BASE_URL_PROD = 'https://souldev.quwanzhi.com'
// 本地开发地址(仅开发者工具模拟器生效;真机自动回退 PROD
// const API_BASE_URL_DEV = 'http://127.0.0.1:9090'

View File

@@ -928,6 +928,8 @@ Page({
let tagType = (e.currentTarget.dataset.tagType || '').trim().toLowerCase()
let pagePath = (e.currentTarget.dataset.pagePath || '').trim()
let mpKey = (e.currentTarget.dataset.mpKey || '').trim()
const hasDatasetPassPhone = !(e.currentTarget.dataset.passPhone == null || e.currentTarget.dataset.passPhone === '')
let explicitPassPhoneConfigured = hasDatasetPassPhone
let passPhone = parseDatasetBool(e.currentTarget.dataset.passPhone)
let phoneParamName = normalizeQueryKey(e.currentTarget.dataset.phoneParamName, 'phone')
@@ -940,11 +942,19 @@ Page({
if (!url) url = pickLinkTagField(cached, ['url', 'linkUrl', 'link_url'], '')
if (!mpKey) mpKey = pickLinkTagField(cached, ['mpKey', 'mp_key', 'appId', 'app_id'], '')
// 透传配置优先取点击节点;节点缺失时回落后台配置
const cachedPassPhone = parseDatasetBool(cached.passPhone)
if (!passPhone) passPhone = cachedPassPhone
const hasCachedPassPhone = !(cached.passPhone == null || cached.passPhone === '')
if (hasCachedPassPhone) {
explicitPassPhoneConfigured = true
const cachedPassPhone = parseDatasetBool(cached.passPhone)
if (!hasDatasetPassPhone) passPhone = cachedPassPhone
}
phoneParamName = normalizeQueryKey(cached.phoneParamName, phoneParamName)
}
}
// 兼容旧配置:历史 miniprogram 标签未配置透传字段时,默认开启手机号透传
if (tagType === 'miniprogram' && !explicitPassPhoneConfigured) {
passPhone = true
}
// CKB 类型:复用 @mention 加好友流程,弹出留资表单
if (tagType === 'ckb') {
@@ -987,24 +997,13 @@ Page({
if (passPhone && phone) {
targetPath = appendQueryToPath(targetPath, phoneParamName, phone)
}
const finalPath = targetPath || ''
const fullTarget = `appId=${linked.appId}${finalPath ? `\npath=${finalPath}` : '\npath=(空)'}`
wx.showModal({
title: '即将跳转小程序',
content: fullTarget,
confirmText: '继续跳转',
cancelText: '取消',
success: (res) => {
if (!res.confirm) return
wx.navigateToMiniProgram({
appId: linked.appId,
path: finalPath,
envVersion: 'release',
success: () => {},
fail: (err) => {
wx.showToast({ title: err.errMsg || '跳转失败', icon: 'none' })
},
})
wx.navigateToMiniProgram({
appId: linked.appId,
path: targetPath || '',
envVersion: 'release',
success: () => {},
fail: (err) => {
wx.showToast({ title: err.errMsg || '跳转失败', icon: 'none' })
},
})
return

View File

@@ -0,0 +1,69 @@
# 测试环境配置air / make dev 时加载,见 .air.toml env_files
APP_ENV=development
# 服务(启动端口在 .env 中配置,修改 PORT 后重启生效)
PORT=9090
GIN_MODE=debug
# 版本号:打包 zip 前在此填写,上传服务器覆盖 .env 后,访问 /health 会返回此版本
APP_VERSION=0.0.0
# 数据库(测试环境 souldev
DB_DSN=souldev:RXW2FeRcRdH2GtXy@tcp(56b4c23f6853c.gz.cdb.myqcloud.com:14413)/souldev?charset=utf8mb4&parseTime=True
# Redis与 n-api 一致REDIS_ADDR / REDIS_PASSWORD / REDIS_DB也可用 REDIS_URL 覆盖)
# 宿主机直连127.0.0.1;容器内需 host.docker.internalcompose extra_hosts勿用 127.0.0.1 指容器自身
REDIS_ADDR=host.docker.internal:26738
REDIS_PASSWORD=WZX7HbnpZErnS6Tm
REDIS_DB=0
# REDIS_ADDR=host.docker.internal:6379
# 远程库启动时跳过 AutoMigrate表已存在避免 information_schema 慢查询);首次建表时注释掉
SKIP_AUTO_MIGRATE=1
# 慢查询阈值(ms),默认 5000避免 200ms 刷屏;设为 0 可恢复 GORM 默认
# SLOW_SQL_THRESHOLD_MS=5000
# DB_DSN=cdb_outerroot:Zhiqun1984@tcp(56b4c23f6853c.gz.cdb.myqcloud.com:14413)/soul_miniprogram?charset=utf8mb4&parseTime=True
# 统一 API 域名(测试环境)
API_BASE_URL=https://souldev.quwanzhi.com
#添加卡若(内部 API用于 /v1/api/scenarios
CKB_LEAD_API_KEY=2y4v5-rjhfc-sg5wy-zklkv-bg0tl
# 存客宝开放 API创建/更新/删除获客计划、拉取设备列表
# - CKB_OPEN_API_KEY开放 API Key开发文档中的 mI9Ol-NO6cS-ho3Py-7Pj22-WyK3A
# - CKB_OPEN_ACCOUNT对应的存客宝登录账号手机号或用户名
CKB_OPEN_API_KEY=mI9Ol-NO6cS-ho3Py-7Pj22-WyK3A
CKB_OPEN_ACCOUNT=karuo1
# 微信小程序配置
WECHAT_APPID=wxb8bbb2b10dec74aa
WECHAT_APPSECRET=3c1fb1f63e6e052222bbcead9d07fe0c
WECHAT_MCH_ID=1318592501
WECHAT_MCH_KEY=wx3e31b068be59ddc131b068be59ddc2
# 支付回调:未设置时由 API_BASE_URL 派生
# WECHAT_NOTIFY_URL=https://souldev.quwanzhi.com/api/miniprogram/pay/notify
# 小程序码/订阅消息跳转版本formal=正式版(默认) | trial=体验版 | developer=开发版
WECHAT_MINI_PROGRAM_STATE=formal
# 微信转账配置API v3
WECHAT_APIV3_KEY=wx3e31b068be59ddc131b068be59ddc2
# 公钥证书(本地或 OSShttps://karuocert.oss-cn-shenzhen.aliyuncs.com/1318592501/apiclient_cert.pem
WECHAT_CERT_PATH=certs/apiclient_cert.pem
# 私钥(线上用 OSShttps://karuocert.oss-cn-shenzhen.aliyuncs.com/1318592501/apiclient_key.pem
WECHAT_KEY_PATH=certs/apiclient_key.pem
WECHAT_SERIAL_NO=4A1DB62CD5C9BE0B6FC51C30621D6F99686E75C5
# 转账回调:未设置时由 API_BASE_URL 派生
# WECHAT_TRANSFER_URL=https://souldev.quwanzhi.com/api/payment/wechat/transfer/notify
# 管理端登录(与 next-project 一致,默认 admin / admin123
# ADMIN_USERNAME=admin
# ADMIN_PASSWORD=admin123
# ADMIN_SESSION_SECRET=soul-admin-secret-change-in-prod
# 可选:信任代理 IP逗号分隔部署在 Nginx 后时填写
# TRUSTED_PROXIES=127.0.0.1,::1
# 跨域 CORS允许的源逗号分隔。未设置时使用默认值含 localhost、soul.quwanzhi.com
CORS_ORIGINS=http://localhost:5175,http://localhost:5174,http://127.0.0.1:5174,https://soul.quwanzhi.com,http://soul.quwanzhi.com,https://souladmin.quwanzhi.com,http://souladmin.quwanzhi.com
# 定时任务密钥:调用 /api/cron/* 时须携带请求头 X-Cron-Secret: <value>(留空则开发模式不校验)
CRON_SECRET=