feat(diy-card): 自定义操作扩至 8 类(2.19.3) — sms/map/link 白名单 + doAct 分支 + map 地址回落
This commit is contained in:
@@ -353,8 +353,9 @@ export function hexToRgba(hex, alpha) {
|
||||
/** 默认动作类型序(图层面板行序与 C 端合并序一致) */
|
||||
export const ACT_TYPES = ['tel', 'wx', 'mail', 'web', 'save'];
|
||||
|
||||
/** 自定义动作类型白名单(doAct 天然消费: tel/wx/mail/copy 分支 + else 兜底) */
|
||||
export const ACT_ACTION_TYPES = ['tel', 'wx', 'mail', 'web', 'copy'];
|
||||
/** 自定义动作类型白名单(doAct 天然消费: tel/wx/mail/copy 分支 + else 兜底;
|
||||
* 2.19.3 扩展: sms 短信/map 导航/link 页面链接(系统链接对话框)) */
|
||||
export const ACT_ACTION_TYPES = ['tel', 'wx', 'mail', 'web', 'copy', 'sms', 'map', 'link'];
|
||||
|
||||
export const ACT_LABEL_DEFAULTS = {
|
||||
tel: '打电话',
|
||||
|
||||
@@ -217,6 +217,10 @@ export default {
|
||||
this.goSaveContact();
|
||||
return;
|
||||
}
|
||||
// map(导航): value 留空回落名片地址(2.19.3)
|
||||
if (act.type === 'map' && !act.value && this.card && this.card.address) {
|
||||
act = Object.assign({}, act, { value: this.card.address });
|
||||
}
|
||||
if (!act.value) return;
|
||||
if (act.type === 'tel') {
|
||||
uni.makePhoneCall({ phoneNumber: act.value, fail: () => {} });
|
||||
@@ -235,6 +239,36 @@ export default {
|
||||
success: () => uni.showToast({ title: '邮箱已复制', icon: 'none' }),
|
||||
});
|
||||
// #endif
|
||||
} else if (act.type === 'sms') {
|
||||
// #ifdef H5
|
||||
window.location.href = 'sms:' + act.value;
|
||||
// #endif
|
||||
// #ifndef H5
|
||||
uni.setClipboardData({
|
||||
data: act.value,
|
||||
success: () => uni.showToast({ title: '号码已复制,请到短信粘贴', icon: 'none' }),
|
||||
});
|
||||
// #endif
|
||||
} else if (act.type === 'map') {
|
||||
uni.setClipboardData({
|
||||
data: act.value,
|
||||
success: () => uni.showToast({ title: '地址已复制,可粘贴到地图导航', icon: 'none' }),
|
||||
});
|
||||
} else if (act.type === 'link') {
|
||||
var isHttp = act.value.indexOf('http://') === 0 || act.value.indexOf('https://') === 0;
|
||||
if (isHttp) {
|
||||
// #ifdef H5
|
||||
window.location.href = act.value;
|
||||
// #endif
|
||||
// #ifndef H5
|
||||
uni.setClipboardData({
|
||||
data: act.value,
|
||||
success: () => uni.showToast({ title: '链接已复制,请在浏览器打开', icon: 'none' }),
|
||||
});
|
||||
// #endif
|
||||
} else {
|
||||
this.$util.redirectTo(act.value, {});
|
||||
}
|
||||
} else {
|
||||
uni.setClipboardData({
|
||||
data: act.value,
|
||||
|
||||
@@ -129,6 +129,10 @@ export default {
|
||||
this.goSaveContact();
|
||||
return;
|
||||
}
|
||||
// map(导航): value 留空回落名片地址(2.19.3)
|
||||
if (act.type === 'map' && !act.value && this.card && this.card.address) {
|
||||
act = Object.assign({}, act, { value: this.card.address });
|
||||
}
|
||||
if (!act.value) return;
|
||||
if (act.type === 'tel') {
|
||||
uni.makePhoneCall({ phoneNumber: act.value, fail: () => {} });
|
||||
@@ -147,6 +151,36 @@ export default {
|
||||
success: () => uni.showToast({ title: '邮箱已复制', icon: 'none' }),
|
||||
});
|
||||
// #endif
|
||||
} else if (act.type === 'sms') {
|
||||
// #ifdef H5
|
||||
window.location.href = 'sms:' + act.value;
|
||||
// #endif
|
||||
// #ifndef H5
|
||||
uni.setClipboardData({
|
||||
data: act.value,
|
||||
success: () => uni.showToast({ title: '号码已复制,请到短信粘贴', icon: 'none' }),
|
||||
});
|
||||
// #endif
|
||||
} else if (act.type === 'map') {
|
||||
uni.setClipboardData({
|
||||
data: act.value,
|
||||
success: () => uni.showToast({ title: '地址已复制,可粘贴到地图导航', icon: 'none' }),
|
||||
});
|
||||
} else if (act.type === 'link') {
|
||||
var isHttp = act.value.indexOf('http://') === 0 || act.value.indexOf('https://') === 0;
|
||||
if (isHttp) {
|
||||
// #ifdef H5
|
||||
window.location.href = act.value;
|
||||
// #endif
|
||||
// #ifndef H5
|
||||
uni.setClipboardData({
|
||||
data: act.value,
|
||||
success: () => uni.showToast({ title: '链接已复制,请在浏览器打开', icon: 'none' }),
|
||||
});
|
||||
// #endif
|
||||
} else {
|
||||
this.$util.redirectTo(act.value, {});
|
||||
}
|
||||
} else {
|
||||
uni.setClipboardData({
|
||||
data: act.value,
|
||||
|
||||
@@ -226,6 +226,11 @@ test('mini.vue + show/self: save(存通讯录)动作全链路(2.17.1)', () => {
|
||||
}
|
||||
assert.match(vue, /Array\.isArray\(c\.rows\)[\s\S]*?map\[r\.field\]/, file + ' 字段从 rows(白名单)提取');
|
||||
assert.doesNotMatch(vue, /doAct\(act\)\s*\{\s*if \(!act \|\| !act\.value\) return;/, file + ' doAct 不再拦 value 为空的 save');
|
||||
// 2.19.3 扩展类型: sms/map/link 分支 + map 空值回落名片地址
|
||||
assert.match(vue, /act\.type === 'map' && !act\.value && this\.card && this\.card\.address/, file + ' map 空值回落名片地址');
|
||||
assert.match(vue, /act\.type === 'sms'\)\s*\{[\s\S]*?window\.location\.href = 'sms:' \+ act\.value;[\s\S]*?号码已复制/, file + ' sms 分支(H5 sms: 链接/非 H5 复制)');
|
||||
assert.match(vue, /act\.type === 'map'\)\s*\{[\s\S]*?地址已复制,可粘贴到地图导航/, file + ' map 分支(复制地址)');
|
||||
assert.match(vue, /act\.type === 'link'\)\s*\{[\s\S]*?indexOf\('http:\/\/'\) === 0 [\s\S]*?\$util\.redirectTo\(act\.value, \{\}\)/, file + ' link 分支(外链 H5 跳转/小程序复制, 站内 redirectTo)');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -461,6 +466,8 @@ test('common.js: normalizeActVis / normalizeActLabels / normalizeCustomActs / no
|
||||
assert.equal(list[0].label, '加群', 'label 保留');
|
||||
assert.equal(list[1].label, '自定义', 'label 缺省');
|
||||
assert.equal(list[1].type, 'tel', '合法 type 保留');
|
||||
// 2.19.3 扩展类型白名单
|
||||
assert.deepEqual(customFn([{ type: 'sms', value: '139' }, { type: 'map', value: '某某大厦' }, { type: 'link', value: '/pages/index/index' }]).map(x => x.type), ['sms', 'map', 'link'], 'sms/map/link 新类型通过白名单');
|
||||
// actOrder(2.19.1): 缺省=历史顺序; 去重+白名单+缺失尾补
|
||||
assert.deepEqual(orderFn(undefined), ['tel', 'wx', 'mail', 'web', 'save'], 'actOrder 缺省=历史顺序');
|
||||
assert.deepEqual(orderFn(['save', 'tel', 'bogus', 'save', 'mail']), ['save', 'tel', 'mail', 'wx', 'web'], '重排去重+非法剔除+缺失尾补');
|
||||
@@ -541,6 +548,8 @@ test('design.html ×2: 图层式管理面板 + 素材图标库 + 预览显隐/
|
||||
// 自定义动作行: 类型 chips / 取值 / 排序 / 删除 / 添加
|
||||
assert.match(html, /diy-card-layer--custom" v-for="\(c, ci\) in nc\.customActs"/, comp + ' 自定义动作图层行');
|
||||
assert.match(html, /:class="\{ active: c\.type === t\.v \}"/, comp + ' 自定义动作类型 chips');
|
||||
assert.match(html, /\{v:'copy',lb:'复制'\},\{v:'sms',lb:'短信'\},\{v:'map',lb:'导航'\},\{v:'link',lb:'页面'\}\]/, comp + ' 类型 chips 含 2.19.3 扩展(短信/导航/页面, web 文案改网址)');
|
||||
assert.match(html, /js-act-syslink" data-scope="custom" :data-idx="ci" v-if="c\.type === 'link'"/, comp + ' link 类型出现「系统链接」选择按钮');
|
||||
assert.match(html, /v-model="c\.value" maxlength="200"/, comp + ' 自定义动作取值输入');
|
||||
assert.match(html, /js-act-lib" data-scope="custom" :data-idx="ci"/, comp + ' 素材图标按钮(自定义动作)');
|
||||
assert.match(html, /nc\.customActs\.splice\(ci - 1, 0, nc\.customActs\.splice\(ci, 1\)\[0\]\)/, comp + ' 上移排序');
|
||||
@@ -612,6 +621,11 @@ test('card-act-icon.js: 类名委托修 2.18 选图标 Bug + $set 写回 + 素
|
||||
assert.match(src, /iconKey: '', svg: '', color: ''/, '缺行防御补齐含 svg 键');
|
||||
assert.match(src, /window\.CARD_ICON_LIB \|\| \{\}/, '弹层渲染消费同源图标库');
|
||||
assert.match(src, /cal-item" data-key=/, '弹层图标网格');
|
||||
// 2.19.3 系统链接对话框委托(link 类型)
|
||||
assert.match(src, /on\('click', '\.js-act-syslink'/, '系统链接走类名委托');
|
||||
assert.match(src, /ns\.select_link\(\{\}, function \(data\)/, '调全局 ns.select_link 打开系统链接对话框');
|
||||
assert.match(src, /data\.wap_url \|\| data\.url/, '回执取 wap_url 写入 value');
|
||||
assert.match(src, /window\.vue\.\$set\(target\.item, 'value', url\)/, '系统链接结果 $set 写回 value');
|
||||
// 反例: 面板不再内联调 openAlbum 选快捷操作图标(2.18 Bug 根因规避)
|
||||
for (const comp of ['show', 'self']) {
|
||||
const html = readFileSync(resolve(BE, 'component/view/diy-card-' + comp + '/design.html'), 'utf8');
|
||||
|
||||
Reference in New Issue
Block a user