/** 消费等级 → 展示标签 */ const CONSUME_LEVEL_LABELS = { 0: { level: 'D', levelKey: 'd' }, 1: { level: 'C', levelKey: 'c' }, 2: { level: 'B', levelKey: 'b' }, 3: { level: 'A', levelKey: 'a' }, 4: { level: 'A+', levelKey: 'aplus' }, 5: { level: 'A++', levelKey: 'aplusplus' } } export function formatMemberDateTime(val) { if (val == null || val === '') return '' const d = val instanceof Date ? val : new Date(val) if (Number.isNaN(d.getTime())) return String(val) const pad = n => String(n).padStart(2, '0') return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}` } export function formatMemberDate(val) { if (val == null || val === '') return '' const s = formatMemberDateTime(val) return s ? s.substring(0, 10) : '' } export function formatMemberMoneyShort(val) { const n = Number(val) || 0 if (n >= 10000) return `${(n / 10000).toFixed(1)}万` return n.toFixed(0) } function pick(obj, ...keys) { if (!obj) return undefined for (const k of keys) { if (obj[k] !== undefined && obj[k] !== null && obj[k] !== '') return obj[k] } return undefined } export function mapKhxxListToSuggestion(row) { const level = CONSUME_LEVEL_LABELS[Number(row.consumeLevel)] || { level: '—', levelKey: 'default' } const lastVisit = formatMemberDate(row.lastVisitTime || row.lastConsumeTime) return { id: row.id, khmc: row.khmc || '无', sjh: row.sjh || '', dah: row.dah || '', gsmdName: row.gsmdName || '无', lastVisit: lastVisit || '无', sleepDays: Number(row.sleepDays) || 0, remainingAmount: formatMemberMoneyShort(row.remainingRightsAmount), totalConsume: formatMemberMoneyShort(row.totalConsumeAmount), level: level.level, levelKey: level.levelKey, displayText: `${row.khmc || '无'} ${row.sjh || ''}` } } function mapRemainingItem(r) { return { ItemName: pick(r, 'itemName', 'ItemName') || '无', ItemPrice: pick(r, 'unitPrice', 'UnitPrice') || 0, SourceType: pick(r, 'sourceType', 'SourceType') || '无', TotalPurchased: pick(r, 'totalQuantity', 'TotalQuantity') || 0, ConsumedCount: pick(r, 'consumedQuantity', 'ConsumedQuantity') || 0, RefundedCount: pick(r, 'refundedQuantity', 'RefundedQuantity') || 0, DeductCount: pick(r, 'deductedQuantity', 'DeductedQuantity') || 0, RemainingCount: pick(r, 'remainingQuantity', 'RemainingQuantity') || 0 } } function applyMemberTypesFromList(member, types) { const names = (types || []).map(t => pick(t, 'typeName', 'TypeName')) member.isBeautyMember = names.includes('生美') ? 1 : 0 member.isMedicalMember = names.includes('医美') ? 1 : 0 member.isTechMember = names.includes('科技部') || names.includes('科美') ? 1 : 0 member.isEducationMember = names.includes('教育部') ? 1 : 0 } /** MemberPortrait overview → 会员详情弹窗左侧数据 */ export function mapOverviewToMember(data) { const base = data?.baseInfo || data?.BaseInfo || {} const behavior = data?.behaviorSummary || data?.BehaviorSummary || {} const assets = data?.assets || data?.Assets || {} const items = assets.remainingItems || assets.RemainingItems || [] const member = { id: pick(base, 'memberId', 'MemberId') || '', dah: pick(base, 'memberCode', 'MemberCode') || '', khmc: pick(base, 'memberName', 'MemberName') || '无', sjh: pick(base, 'mobile', 'Mobile') || '', xb: pick(base, 'gender', 'Gender') || '', gsmdName: pick(base, 'storeName', 'StoreName') || '', storeName: pick(base, 'storeName', 'StoreName') || '', zcsj: formatMemberDate(pick(base, 'registerTime', 'RegisterTime')) || '无', jdqd: pick(base, 'channel', 'Channel') || '无', tjrName: pick(base, 'referrerName', 'ReferrerName') || '无', expandUserName: pick(base, 'expandUserName', 'ExpandUserName') || '无', mainHealthUserName: pick(base, 'mainHealthUserName', 'MainHealthUserName') || '无', subHealthUserName: pick(base, 'subHealthUserName', 'SubHealthUserName') || '无', lxdz: pick(base, 'address', 'Address') || '无', bz: pick(base, 'remark', 'Remark') || '无', yanglsr: pick(base, 'yanglsr', 'Yanglsr') ? formatMemberDate(base.yanglsr || base.Yanglsr) : '', yinlsr: pick(base, 'yinlsr', 'Yinlsr') || '', firstVisitTime: formatMemberDateTime(pick(base, 'firstVisitTime', 'FirstVisitTime')) || '无', lastVisitTime: formatMemberDateTime(pick(base, 'lastVisitTime', 'LastVisitTime')), lastVisit: formatMemberDate(pick(base, 'lastVisitTime', 'LastVisitTime')), sleepDays: Number(pick(base, 'sleepDays', 'SleepDays')) || 0, consumeLevel: Number(pick(base, 'consumeLevel', 'ConsumeLevel')) || 0, totalConsumeAmount: pick(behavior, 'totalConsumeAmount', 'TotalConsumeAmount') || 0, totalBillingAmount: pick(behavior, 'totalBillingAmount', 'TotalBillingAmount') || 0, remainingRightsAmount: pick(behavior, 'remainingRightsAmount', 'RemainingRightsAmount') || 0, lastConsumeTime: formatMemberDateTime(pick(behavior, 'lastConsumeTime', 'LastConsumeTime')), RemainingItems: items.map(mapRemainingItem), isBeautyMember: 0, isMedicalMember: 0, isTechMember: 0, isEducationMember: 0 } applyMemberTypesFromList(member, base.memberTypes || base.MemberTypes) return member } export function mapBillingRecords(list) { return (list || []).map(row => ({ BillingDate: formatMemberDateTime(pick(row, 'billingDate', 'BillingDate')), StoreName: pick(row, 'storeName', 'StoreName') || '无', CreatorName: pick(row, 'creatorName', 'CreatorName') || '无', HealthCoachNames: pick(row, 'healthCoachNames', 'HealthCoachNames') || '无', TechTeacherNames: pick(row, 'techTeacherNames', 'TechTeacherNames') || '无', Items: pick(row, 'items', 'Items') || '无', Amount: pick(row, 'amount', 'Amount') || 0, DebtAmount: pick(row, 'debtAmount', 'DebtAmount') || 0, ActivityName: pick(row, 'activityName', 'ActivityName') || '无' })) } export function mapConsumeRecords(list) { return (list || []).map(row => ({ ConsumeDate: formatMemberDateTime(pick(row, 'consumeDate', 'ConsumeDate')), StoreName: pick(row, 'storeName', 'StoreName') || '无', OperatorName: pick(row, 'operatorName', 'OperatorName') || '无', HealthCoachNames: pick(row, 'healthCoachNames', 'HealthCoachNames') || '无', TechTeacherNames: pick(row, 'techTeacherNames', 'TechTeacherNames') || '无', Items: pick(row, 'items', 'Items') || '无', Amount: pick(row, 'amount', 'Amount') || 0, LaborCost: pick(row, 'laborCost', 'LaborCost') || 0 })) } export function mapRefundRecords(list) { return (list || []).map(row => ({ RefundDate: formatMemberDateTime(pick(row, 'refundDate', 'RefundDate')), StoreName: pick(row, 'storeName', 'StoreName') || '无', RefundAmount: pick(row, 'refundAmount', 'RefundAmount') || 0, ActualRefundAmount: pick(row, 'actualRefundAmount', 'ActualRefundAmount') || 0, RefundReason: pick(row, 'refundReason', 'RefundReason') || '无' })) } export function mapBookingRecords(list) { return (list || []).map(row => ({ AppointmentDate: formatMemberDateTime(pick(row, 'appointmentDate', 'AppointmentDate')), StoreName: pick(row, 'storeName', 'StoreName') || '无', InviterName: pick(row, 'inviterName', 'InviterName') || '无', HealthCoachName: pick(row, 'healthCoachName', 'HealthCoachName') || '无', ExperienceItem: pick(row, 'experienceItem', 'ExperienceItem') || '无', Status: pick(row, 'status', 'Status') || '无', NoDealRemark: pick(row, 'noDealRemark', 'NoDealRemark') || '' })) } export function mapInviteRecords(list) { return (list || []).map(row => ({ InviteDate: formatMemberDateTime(pick(row, 'inviteDate', 'InviteDate')), StoreName: pick(row, 'storeName', 'StoreName') || '无', InviterName: pick(row, 'inviterName', 'InviterName') || '无', ContactTime: formatMemberDateTime(pick(row, 'contactTime', 'ContactTime')), ContactRecord: pick(row, 'contactRecord', 'ContactRecord') || '无', PhoneValid: pick(row, 'phoneValid', 'PhoneValid') || '无' })) } export function mapServiceLogRecords(list) { return (list || []).map(row => ({ CreateTime: formatMemberDateTime(pick(row, 'createTime', 'CreateTime')), CreatorName: pick(row, 'creatorName', 'CreatorName') || '无', Remark: pick(row, 'remark', 'Remark') || '无', KjbRemark: pick(row, 'kjbRemark', 'KjbRemark') || '' })) } export function mapOldLogRecords(list) { return (list || []).map(row => ({ CreateTime: formatMemberDateTime(pick(row, 'createTime', 'CreateTime')), OrderNo: pick(row, 'orderNo', 'OrderNo') || '无', MemberName: pick(row, 'memberName', 'MemberName') || '无', Remarks: pick(row, 'remarks', 'Remarks') || '无' })) } export function extractPortraitList(res) { const data = res?.data || {} const list = data.list || data.List || [] const total = data.total ?? data.Total ?? list.length return { list, total } }