Files
lucky_shop/common/js/card-api.js

568 lines
23 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 名片云(card addon)API 收口层
*
* 单一事实来源:后端《名片云(card addon)API 对接文档》CARD_API_REFERENCE.md(2026-10-13)
* 文档与源码如有出入,以源码为准;URL 路径一个字符都不能变,只做收口不做改名。
*
* 收口要求(来自后端 checklist):
* 1. 所有 /card/api/* URL 必须集中在本层,页面不得再直连字面量;
* 2. 统一走项目请求工具(自动带 token / uniacid),任何接口不传 site_id;
* 3. 失败分支统一 toast(message);「不存在」类错误按"内容不存在或已删除"提示;
* 4. card/update 只传编辑过的键(键存在才写、空串=清空、键缺席=不擦除);
* 5. 详情/列表渲染富化字段用 *_list 解码键,不解析原始 JSON 串;
* 6. 编辑页对 locked_fields 命中的字段渲染只读;
* 7. recognize 成功后检查 deduped,为 true 时提示"已存在同手机号名片";
* 8. 分页参数 page_size 不超过 100;
* 9. 名片路由参数用 card_id(字符串),人脉/线索用 id(数字),不要混用。
*
* 用法(页面内 this.$cardApi):
* this.$cardApi.cardLists({ data: { page: 1 }, success: res => {}, fail: () => {} })
*
* 注意:本层只做"URL 收口 + 通道选择",不做业务加工;
* 业务字典(状态/来源/字段白名单)随端口导出,供各页面复用。
*/
import Http from './http.js';
/** 所有端点路径(与后端文档逐一比对,改动需两边同步) */
export const CARD_API_URL = {
// === 名片夹 /card/api/card/* ===
CARD_LISTS: '/card/api/card/lists',
CARD_DETAIL: '/card/api/card/detail',
CARD_UPDATE: '/card/api/card/update',
CARD_FAVORITE: '/card/api/card/toggleFavorite', // 收藏(双向 toggle, 后端 2.9.12)
CARD_CREATE: '/card/api/card/create', // 新建数字名片(后端源码已有, 文档未列; 以源码为准)
CARD_CLAIM: '/card/api/card/claim',
CARD_RECOGNIZE: '/card/api/card/recognize',
CARD_RETRY: '/card/api/card/retry',
CARD_RECOGNIZE_BATCH: '/card/api/card/recognizeBatch',
CARD_DELETE: '/card/api/card/delete', // 删除自己的名片(软删, 2.11.91)
// === 跟进完成态 2.11.3 /card/api/card/* ===
CARD_FOLLOW_DONE: '/card/api/card/followDone',
// === 访客轨迹 2.11.4 /card/api/card/* ===
CARD_VIEWS: '/card/api/card/views',
// === 员工建卡申请 2.11.15 /card/api/apply/* ===
APPLY_SUBMIT: '/card/api/apply/submit',
APPLY_STATUS: '/card/api/apply/status',
// === 人脉库 /card/api/contact/* ===
CONTACT_LISTS: '/card/api/contact/lists',
CONTACT_ADD: '/card/api/contact/add',
CONTACT_INFO: '/card/api/contact/info',
CONTACT_UPDATE: '/card/api/contact/update',
CONTACT_DELETE: '/card/api/contact/delete',
CONTACT_TO_LEAD: '/card/api/contact/toLead',
// === 潜在客户 /card/api/lead/* ===
LEAD_LISTS: '/card/api/lead/lists',
LEAD_SET_STATUS: '/card/api/lead/setStatus',
// === 交换名片 /card/api/exchange/* ===
EXCHANGE_LISTS: '/card/api/exchange/lists',
EXCHANGE_AGREE: '/card/api/exchange/agree',
EXCHANGE_IGNORE: '/card/api/exchange/ignore',
// === 名片设计(员工端可选样式, 后端 v2) /card/api/design/* ===
// 预设列表必须与商家后台 CardTemplatePresets 同源(避免前端自建漂移)
// ⚠ v2 路径无 /card/ 段: 初版 /card/api/card/design/* 在本框架 action 单段路由下 404
CARD_DESIGN_PRESETS: '/card/api/design/presets', // 预设列表(同源后台 CardTemplatePresets)
CARD_DESIGN_SAVE: '/card/api/design/save', // 应用预设/保存本卡样式
// === 企业名片 /card/api/enterprise/* (2.13.6) ===
// 业务模型: 企业卡片 owner_id=0(店铺级), 同一时刻仅 1 张 is_active=1 生效;
// 名片区三模式 header_mode: official(指定/默认官方企业卡) / self(员工自选个人卡) / staff(员工轮播)
ENTERPRISE_DETAIL: '/card/api/enterprise/detail', // GET ?card_id= 不传=当前生效卡
ENTERPRISE_SAVE: '/card/api/enterprise/save', // POST {card_id?,fields?,design?,header_mode?,official_card_id?}
ENTERPRISE_MINE: '/card/api/enterprise/mine', // GET 自己名下企业卡列表
ENTERPRISE_ACTIVATE: '/card/api/enterprise/activate', // POST {card_id} 切换生效(互斥)
ENTERPRISE_CHOOSE_SELF: '/card/api/enterprise/chooseSelf', // POST {card_id} 员工自选展示个人卡
ENTERPRISE_DELETE: '/card/api/enterprise/delete' // POST {card_id} 删候选卡(生效卡禁删)
};
/**
* 社交媒体类型白名单:必须与后端 CardRichFields::SOCIAL_TYPES 保持一致(增减需两边同步)。
* type 非法或 value 为空的条目会被后端静默丢弃。
* ⚠️ 2026-10-13:telegram / messenger 由独立标量字段软下线,统一并入本数组;
* 旧数据后端读取时自动合并进 socials_list(见 CARD_API_REFERENCE.md 3.3)。
*/
export const SOCIAL_TYPES = [
{ key: 'alipay', label: '支付宝' },
{ key: 'douyin', label: '抖音' },
{ key: 'wxvideo', label: '视频号' },
{ key: 'xiaohongshu', label: '小红书' },
{ key: 'weibo', label: '微博' },
{ key: 'kuaishou', label: '快手' },
{ key: 'bilibili', label: '哔哩哔哩' },
{ key: 'qq', label: 'QQ' },
{ key: 'linkedin', label: 'LinkedIn' },
{ key: 'facebook', label: 'Facebook' },
{ key: 'instagram', label: 'Instagram' },
{ key: 'x', label: 'X' },
{ key: 'telegram', label: 'Telegram' },
{ key: 'messenger', label: 'Messenger' },
{ key: 'other', label: '其他' }
];
/** 富化字段上限:与后端 CardRichFields::MAX_* 一致 */
export const RICH_FIELD_LIMITS = {
MAX_MOBILES: 5,
MAX_SOCIALS: 10,
MAX_CUSTOM: 10
};
/** 线索跟进状态:与后端 Lead::STATUSES 一致(0-3,其它值报「参数不合法」) */
export const LEAD_STATUS = [
{ value: 0, label: '新客户' },
{ value: 1, label: '已联系' },
{ value: 2, label: '已成交' },
{ value: 3, label: '无效' }
];
/** 人脉来源:与后端 Contact::SOURCES 一致(scan/exchange 暂无产生入口) */
export const CONTACT_SOURCES = [
{ value: 'manual', label: '手工录入' },
{ value: 'lead_in', label: '潜在客户转入' },
{ value: 'scan', label: '扫描' },
{ value: 'exchange', label: '交换' }
];
/** 名片来源:与后端 relation.source_type 一致 */
export const CARD_SOURCE_TYPES = [
{ value: 'manual', label: '手动创建' },
{ value: 'manual_batch', label: '批量制作' },
{ value: 'scan', label: '扫描识别' },
{ value: 'import_csv', label: 'CSV 导入' },
{ value: 'import_xlsx', label: 'Excel 导入' },
{ value: 'clone', label: '克隆' },
{ value: 'api', label: '接口创建' }
];
/**
* 名片编辑标量字段:与后端 BusinessCardFieldNormalizer 输出对齐。
* ⚠️ 2026-10-13:telegram / messenger 已软下线为独立标量(传了也被忽略),
* 统一走 fields.socials 数组按类型添加;读取时旧值自动合并进 socials_list。
*/
export const CARD_FIELDS = [
'name', 'company', 'job_title', 'avatar',
'mobile', 'phone', 'email', 'website', 'wechat',
'country', 'province', 'city', 'address', 'postal_code',
'bio'
];
/** 人脉可更新白名单:与后端 Contact::EDITABLE_FIELDS 一致 */
export const CONTACT_FIELDS = [
'name', 'mobile', 'company', 'job_title', 'wechat', 'email', 'website', 'address', 'remark', 'status'
];
const CardApi = {
url: CARD_API_URL,
/* ================= 名片夹 ================= */
/**
* 我的名片列表
* @param {Object} p { page, page_size(<=100), keyword, success, fail }
* 返回 data: { list, count, page_count }
*/
cardLists(p) {
Http.sendRequest(Object.assign({ url: CARD_API_URL.CARD_LISTS }, p || {}));
},
/**
* 卡片详情
* @param {Object} p { card_id, success, fail }
* 返回 data: { relation, source, share_list }
*/
cardDetail(p) {
Http.sendRequest(Object.assign({ url: CARD_API_URL.CARD_DETAIL }, p || {}));
},
/**
* 更新卡片(normalize 语义:键存在才写;空串=清空;键缺席=不擦除)
* 局部更新时只传用户实际编辑过的键。走 JSON body(fields 为嵌套对象)。
* @param {Object} p { card_id, fields, success, fail }
*/
cardUpdate(p) {
Http.sendJson(Object.assign({ url: CARD_API_URL.CARD_UPDATE }, p || {}));
},
/**
* 新建数字名片(商家端批量制作/单张新建入口)
* 入参:`fields`(与 card/update 同结构,`name` 必填)+ 可选 `owner_id`(指定归属员工,0=未归属待认领)
* 返回 `data`:`{ card_id, ...relation }`(前端用 data.card_id 跳详情)
* ⚠️ 该端点后端源码已实现但旧文档未列出,按「文档与源码出入以源码为准」收口。
*/
cardCreate(p) {
Http.sendJson(Object.assign({ url: CARD_API_URL.CARD_CREATE }, p || {}));
},
/**
* 认领名片(商家后台建的卡未归属 owner_id=0,员工认领到自己名下)
* 入参(二选一, claim_code 优先): { data: { claim_code } } 或 { data: { card_id } }
* 成功 data.claimed: true=新认领, false=早已是自己的(幂等)
* 文档: card_claim_api.md(POST /card/api/card/claim,token 自动带)
* @param {Object} p { data: { claim_code | card_id }, success, fail }
*/
cardClaim(p) {
Http.sendRequest(Object.assign({ url: CARD_API_URL.CARD_CLAIM }, p || {}));
},
/**
* 切换收藏(双向 toggle,幂等可逆:未收藏→置1,已收藏→置0)
* 直接用返回值 data.is_favorite 回填 UI,前端不自行判断状态。
* @param {Object} p { data: { card_id }, success, fail }
* 返回 data: { card_id, is_favorite: 0|1 }
* 拒绝(message 直接 toast): 卡不存在 / 非自己名下卡(统一「名片不存在」) / 参数不合法 / 未登录
*/
cardToggleFavorite(p) {
Http.sendJson(Object.assign({ url: CARD_API_URL.CARD_FAVORITE }, p || {}));
},
/**
* 删除自己的名片(软删, 2.11.91)
* 文档: CARD_DELETE_API.md(POST /card/api/card/delete,token 自动带,不传 site_id)
* 通道: 与 cardClaim/cardFollowDone 同款 sendRequest(表单编码);只需 card_id 一个字段
* 交互: 调用前页面必须已做二次确认;成功后 toast「已删除」并刷新列表(接口不再返回该卡)
* 口径: 「卡片不存在」是故意模糊(他人/已删/不存在同一文案),前端统一按 message toast,不特殊处理
* @param {Object} p { data: { card_id }, success, fail }
*/
cardDelete(p) {
Http.sendRequest(Object.assign({ url: CARD_API_URL.CARD_DELETE }, p || {}));
},
/**
* 识别建卡
* @param {Object} p { media_path, media_type?, source_type?, success, fail }
* 返回 data: { source_id, relation_id, card_id, deduped, fields }
* deduped=true 表示站点内已有同手机号名片,未新建,前端提示"已存在同名片"
*/
cardRecognize(p) {
Http.sendRequest(Object.assign({ url: CARD_API_URL.CARD_RECOGNIZE }, p || {}));
},
/**
* 识别失败重试(仅本站 + status=failed 的来源可重试,有次数上限)
* @param {Object} p { source_id, success, fail }
*/
cardRetry(p) {
Http.sendRequest(Object.assign({ url: CARD_API_URL.CARD_RETRY }, p || {}));
},
/**
* 批量识别(1~10 条,逐项独立成败)
* @param {Object} p { items: [{ source_type?, media_type?, media_path, media_key? }], success, fail }
* 返回 data: { items: [{ ok, message, data }], ok, failed }
*/
cardRecognizeBatch(p) {
Http.sendJson(Object.assign({ url: CARD_API_URL.CARD_RECOGNIZE_BATCH }, p || {}));
},
/**
* 标记跟进完成(2.11.3 跟进闭环)
* 行级归属: 只能标记自己名下的名片(与收藏/认领同一套口径)
* 成功 data: { card_id, follow_up_done: 1 }
* 失败 message 直接 toast: 卡片不存在 / 只能标记自己名下的名片
* @param {Object} p { data: { card_id }, success, fail }
*/
cardFollowDone(p) {
Http.sendRequest(Object.assign({ url: CARD_API_URL.CARD_FOLLOW_DONE }, p || {}));
},
/**
* 访客轨迹(2.11.4 谁看了我)
* 入参(全部可选): { data: { card_id?, page?, page_size?(<=50, 建议20) } }
* 不传 card_id = 当前员工名下全部名片; 成功 data: { list, total, page, page_size,
* summary: { today_pv, today_uv, total_pv, total_uv } }
* @param {Object} p { data: {...}, success, fail }
*/
cardViews(p) {
Http.sendRequest(Object.assign({ url: CARD_API_URL.CARD_VIEWS }, p || {}));
},
/* ================= 人脉库 ================= */
/**
* 人脉列表
* @param {Object} p { page, page_size(<=100), keyword, source?, status?, success, fail }
* 返回 data: { list, count, page_count }
*/
contactLists(p) {
Http.sendRequest(Object.assign({ url: CARD_API_URL.CONTACT_LISTS }, p || {}));
},
/**
* 新增人脉
* @param {Object} p { fields: { name(必填), company?, ... }, success, fail }
*/
contactAdd(p) {
Http.sendJson(Object.assign({ url: CARD_API_URL.CONTACT_ADD }, p || {}));
},
/**
* 人脉详情(编辑页回填;id 为数字自增主键,注意与名片 card_id 字符串不同)
* @param {Object} p { id, success, fail }
*/
contactInfo(p) {
Http.sendRequest(Object.assign({ url: CARD_API_URL.CONTACT_INFO }, p || {}));
},
/**
* 更新人脉(兼容 fields 对象或顶层平铺字段)
* @param {Object} p { id, fields?, ...平铺字段, success, fail }
*/
contactUpdate(p) {
Http.sendJson(Object.assign({ url: CARD_API_URL.CONTACT_UPDATE }, p || {}));
},
/**
* 删除人脉(真删不可恢复,前端需二次确认弹窗)
* @param {Object} p { id, success, fail }
*/
contactDelete(p) {
Http.sendRequest(Object.assign({ url: CARD_API_URL.CONTACT_DELETE }, p || {}));
},
/**
* 人脉 → 潜在客户(不删人脉行;同员工同手机号已转过则报错)
* @param {Object} p { id, success, fail }
*/
contactToLead(p) {
Http.sendRequest(Object.assign({ url: CARD_API_URL.CONTACT_TO_LEAD }, p || {}));
},
/* ================= 潜在客户 ================= */
/**
* 线索列表(自己名下名片收到的线索 + 自己从人脉转入的线索)
* @param {Object} p { page, page_size(<=100), status?(0-3), keyword, success, fail }
* 返回 data: { list, count, page_count }
*/
leadLists(p) {
Http.sendRequest(Object.assign({ url: CARD_API_URL.LEAD_LISTS }, p || {}));
},
/**
* 更新跟进状态(status 只能是 0/1/2/3)
* @param {Object} p { id, status, success, fail }
* 返回 data: { id, status }
*/
leadSetStatus(p) {
Http.sendRequest(Object.assign({ url: CARD_API_URL.LEAD_SET_STATUS }, p || {}));
},
/* ================= 交换名片 ================= */
/**
* 待处理交换请求列表(返回 status=0;已同意/已忽略员工端不可见)
* @param {Object} p { page, page_size(<=100), success, fail }
* 返回 data: { list:[{ id, from_card_id, name, avatar, job_title, company,
* create_time, create_time_txt, status }], count, page_count }
* ⚠️ 详情页红点计数技巧: lists?page=1&page_size=1 取 count 即可
* ⚠️ 后端契约要求 lists 走 GET(分页在 query); 而 Http.sendRequest 是
* 「带 data 就发 POST」的语义, 所以这里把分页拼进 url、不传 data,
* 否则会被发成 POST 导致接口不匹配、列表恒为空。
*/
exchangeLists(p) {
const opt = Object.assign({}, p || {});
const src = opt.data || opt;
const page = src.page || 1;
const pageSize = src.page_size || 20;
delete opt.data;
delete opt.page;
delete opt.page_size;
opt.url = CARD_API_URL.EXCHANGE_LISTS + '?page=' + page + '&page_size=' + pageSize;
Http.sendRequest(opt);
},
/**
* 同意交换(后端自动双方建人脉,前端无需再调 contact/add)
* 幂等: 同侧已存在同手机号人脉时 receiver_created=0,仍是成功,不当失败
* @param {Object} p { data: { id }, success, fail }
* 返回 data: { id, status:1, receiver_created, initiator_created }
*/
exchangeAgree(p) {
Http.sendJson(Object.assign({ url: CARD_API_URL.EXCHANGE_AGREE }, p || {}));
},
/**
* 忽略交换(仅本方隐藏 status=2,对方不发通知、可再次发起)
* @param {Object} p { data: { id }, success, fail }
* 返回 data: { id, status:2 }
*/
exchangeIgnore(p) {
Http.sendJson(Object.assign({ url: CARD_API_URL.EXCHANGE_IGNORE }, p || {}));
},
/**
* 同意交换后「校验 + 兜底」建人脉(页面点「同意」后必调;幂等,可安全重复调用)。
* 背景: 后端声明 CardExchange::agree 会双向互存人脉(我方人脉收对方名片 / 对方人脉收我方名片),
* 但实测出现「同意成功、对方名片却没进我的人脉」, 故前端不再只信 receiver_created,
* 统一在同意后按「对方名片编号」校验一次: 我的人脉里没有同手机号记录才补建。
* 流程: 取对方名片详情 → 按手机号查我的人脉 → 不存在则以 source=exchange 新建人脉。
* 幂等: 同手机号人脉已存在(含后端已建)时 created=0, 与后台已建不会重复。
* @param {Object} p { fromCardId, success, fail }
* 回调 done(data): { code, created, existed } created=1 新建 / 0 已存在或无需建;
* existed = 命中的同手机号人脉行(未命中为 null), 供页面提示「人脉中已有该联系人」。
*/
ensureExchangeContact(p) {
const self = this;
const done = p.success, fail = p.fail;
const finish = (d) => { typeof done === 'function' && done(d); };
const fromCardId = p.fromCardId;
if (!fromCardId) { finish({ code: 0, created: 0 }); return; }
this.cardDetail({
data: { card_id: fromCardId },
success: res => {
if (res.code != 0) { typeof fail === 'function' && fail(res); return; }
const r = (res.data && (res.data.relation || res.data)) || {};
const mobile = r.mobile || '';
const fields = {
name: r.name || '',
company: r.company || '',
job_title: r.job_title || '',
mobile: mobile,
source: 'exchange'
};
// 富化字段仅在对方有名片值时带上(空串=清空语义, 新建人脉时不传空键)
if (r.wechat) fields.wechat = r.wechat;
if (r.email) fields.email = r.email;
if (r.website) fields.website = r.website;
if (r.address) fields.address = r.address;
const add = () => self.contactAdd({
data: { source: 'exchange', fields: fields },
success: res2 => {
// code!=0(如手机号已存在被拒): 交换已同意成功, 兜底不打扰用户, 按无需新建收口
const ok = res2 && res2.code == 0;
finish({ code: ok ? 0 : ((res2 && res2.code) || 0), created: ok ? 1 : 0, raw: res2 });
},
fail: err => { typeof fail === 'function' && fail(err); }
});
// 按手机号去重: 已存在同手机号人脉则不重复建(兼容后台已建 / 重复同意)
if (mobile) {
self.contactLists({
data: { page: 1, page_size: 20, keyword: mobile },
success: res3 => {
const d3 = res3.data || {};
const list = Array.isArray(d3) ? d3 : (d3.list || []);
const hit = list.find(c => (c.mobile || '') === mobile);
// 命中: 对方已在我的人脉里(可能显示为旧姓名), 不覆盖用户维护过的数据, 只回传命中行
if (hit) { finish({ code: 0, created: 0, existed: hit }); return; }
add();
},
fail: () => add()
});
} else {
add();
}
},
fail: err => { typeof fail === 'function' && fail(err); }
});
},
/* ================= 员工建卡申请 2.11.15 ================= */
/**
* 提交建卡申请(空态申请 → 商家审批 → 自动建卡归属)
* 约束: 同一会员同时只允许一条待审申请(重复提交后端会拒)
* 入参: { data: { name, mobile } }
* @param {Object} p { data: { name, mobile }, success, fail }
*/
applySubmit(p) {
Http.sendRequest(Object.assign({ url: CARD_API_URL.APPLY_SUBMIT }, p || {}));
},
/**
* 查询我的建卡申请状态(进入名片夹/空态时调用或轮询)
* 成功 data: { status: 0 待审/1 已同意/2 已拒绝, status_text, note, has_card }
* @param {Object} p { success, fail }
*/
applyStatus(p) {
Http.sendRequest(Object.assign({ url: CARD_API_URL.APPLY_STATUS }, p || {}));
},
/* ================= 名片设计(员工端可选样式) ================= */
/**
* 拉取名片预设列表(与商家后台 CardTemplatePresets 同一份, 同源)
* 成功 data: { list:[{ key, name, desc, thumb,
* design:{ theme_color, text_color, bg_color, layout, cover, font_family,
* font_scale, card_radius, header_gradient_end, header_gradient_angle, quick_style } }] }
* @param {Object} p { success, fail }
*/
cardDesignPresets(p) {
Http.sendRequest(Object.assign({ url: CARD_API_URL.CARD_DESIGN_PRESETS }, p || {}));
},
/**
* 应用预设 / 保存本卡样式(员工端选择后台预设后落库)
* 入参(包在 data 里): { card_id, preset_key } —— 后端按 preset_key 取 CardTemplatePresets
* 的 design 合并进本卡 lucky_card_design(非空覆盖), 返回 { code:0 }
* @param {Object} p { data: { card_id, preset_key }, success, fail }
*/
cardDesignSave(p) {
Http.sendJson(Object.assign({ url: CARD_API_URL.CARD_DESIGN_SAVE }, p || {}));
},
/* ================= 企业名片 2.13.6 ================= */
/**
* 企业名片详情(核心)
* GET ?card_id= 不传返回当前生效企业名片;传候选卡 id 可预览(is_active=0)
* 成功 data: { card_id, is_active, is_owner, fields:{name,company,job_title,mobile,email,
* website,address,wechat,avatar,bio,name_en,company_en,job_title_en,bio_en},
* design:{theme_color,bg_color,text_color,template_id,canvas,header_mode,official_card_id},
* header:{mode,official_card_id,official,self,staff} }
* 渲染: 名片区按 header.mode 取 official/self/staff 数据, 内容区用 fields+design.canvas
* 失败「企业名片不存在」→ 前端空态引导去管理端创建
* @param {Object} p { data: { card_id? }, success, fail }
*/
enterpriseDetail(p) {
Http.sendRequest(Object.assign({ url: CARD_API_URL.ENTERPRISE_DETAIL }, p || {}));
},
/**
* 保存企业名片(后台/会员;owner_id=0 的卡会员不可改)
* @param {Object} p { data: { card_id?, fields?, design?, header_mode?, official_card_id? }, success, fail }
*/
enterpriseSave(p) {
Http.sendJson(Object.assign({ url: CARD_API_URL.ENTERPRISE_SAVE }, p || {}));
},
/**
* 我的企业名片列表(自己名下)
* 成功 data: { list: [{ card_id, name, is_active }] }
* @param {Object} p { success, fail }
*/
enterpriseMine(p) {
Http.sendRequest(Object.assign({ url: CARD_API_URL.ENTERPRISE_MINE }, p || {}));
},
/**
* 切换生效企业名片(互斥:全店仅 1 张 is_active=1,仅能切自己名下的卡)
* @param {Object} p { data: { card_id }, success, fail }
*/
enterpriseActivate(p) {
Http.sendJson(Object.assign({ url: CARD_API_URL.ENTERPRISE_ACTIVATE }, p || {}));
},
/**
* 员工自选展示名片(self 模式):card_id 必须是自己名下的 contact 卡
* 选择按会员存储;detail 的 header.self.chosen=1 表示已自选
* @param {Object} p { data: { card_id }, success, fail }
*/
enterpriseChooseSelf(p) {
Http.sendJson(Object.assign({ url: CARD_API_URL.ENTERPRISE_CHOOSE_SELF }, p || {}));
},
/**
* 删除企业名片(会员端;生效卡不可删,删除候选卡会清理官方名片引用)
* @param {Object} p { data: { card_id }, success, fail }
*/
enterpriseDelete(p) {
Http.sendJson(Object.assign({ url: CARD_API_URL.ENTERPRISE_DELETE }, p || {}));
}
};
export default CardApi;