Files
zt-closet-wxmini-frontend/miniprogram/utils/guest.ts
T
zhengchiliu f0503c7ad7 feat(guest): 支持游客态浏览示例衣物与搭配
游客可点开示例衣物详情与搭配抽屉,不再在浏览路径上要求登录。
2026-09-17 11:41:42 +08:00

110 lines
4.0 KiB
TypeScript

import { ClothesItem, HoroscopeData } from '../types/models'
import { DAMO_CLOTHES, DAMO_OUTFIT_ITEMS } from '../damo/damo'
import { logger } from './logger'
// 日志模块名
const LOG = 'guest'
/**
* 游客态唯一数据源:未登录浏览时展示的本地示例内容 + 统一登录引导。
*
* 合规背景(微信审核整改):
* 1. 打开小程序不得直接要求授权登录,用户应能先浏览体验功能服务;
* 2. 示例内容必须能完整浏览与点开查看详情,不得在浏览路径上要求登录;
* 3. 仅在用户主动使用受限功能时,才由用户自行选择是否登录。
*
* 本模块不发起任何网络请求、不改动登录态:示例数据全部来自本地 damo 素材。
*/
// 衣橱示例:damo 素材(含包内图片路径),分类筛选由调用方按 category_main 本地完成
export const GUEST_WARDROBE: ClothesItem[] = DAMO_CLOTHES
// 穿搭示例:游客态只展示这一套(黑色短袖JK水手服上衣 + 藏青色百褶半身裙)
export interface GuestOutfit {
key: string
name: string
scene: string
desc: string
items: ClothesItem[]
}
export const GUEST_OUTFIT: GuestOutfit = {
key: 'damo-outfit-1',
name: '藏青学院一套',
scene: '校园上课',
desc: '黑色短袖水手服上衣配藏青百褶半身裙,酒红蝴蝶结与白条纹作点缀',
items: DAMO_OUTFIT_ITEMS,
}
// 分享示例
export interface GuestShare {
key: string
kind: 'closet' | 'outfit'
title: string
typeText: string
expireText: string
}
export const GUEST_SHARES: GuestShare[] = [
{ key: 'gs1', kind: 'closet', title: '衣柜分享 · 12 件', typeText: '全量衣橱', expireText: '示例内容' },
{ key: 'gs2', kind: 'outfit', title: '藏青学院一套', typeText: '穿搭分享 · 2 件', expireText: '示例内容' },
]
// 运势示例:日期取当天,保证页头日期不出现过去时间
export function guestHoroscope(): HoroscopeData {
const d = new Date()
const pad = (n: number) => (n < 10 ? `0${n}` : String(n))
return {
stat_date: Number(`${d.getFullYear()}${pad(d.getMonth() + 1)}${pad(d.getDate())}`),
zodiac: '天秤座',
overall_score: 4,
love_score: 4,
career_score: 3,
wealth_score: 3,
daily_text:
'适合整理衣橱的一天:把常穿的几件放在最容易拿到的位置,出门前的犹豫会少很多。新的配色值得记录,晚间适合与朋友聊聊近况。',
lucky_color: '蓝色',
lucky_number: '7',
}
}
// 登录跳转防抖:连续点击多个受限入口时只跳一次
let lastNavAt = 0
/**
* 统一登录引导入口(游客态所有受限操作都走这里)。
*
* 与 utils/request.ts 的 redirectToLogin 的区别:
* - redirectToLogin 用于「登录态失效」的被动兜底,reLaunch 清栈;
* - goLogin 用于用户主动使用受限功能的场景,navigateTo 保留返回路径,
* 用户可随时返回继续浏览,不会被强制清栈。
*/
export function goLogin(options: { redirect?: string } = {}): void {
const pages = typeof getCurrentPages === 'function' ? getCurrentPages() : []
const current = pages[pages.length - 1]
if (current && current.route === 'pages/login/login') {
logger.debug(LOG, '已在登录页,忽略本次登录引导')
return
}
const now = Date.now()
if (now - lastNavAt < 800) {
logger.debug(LOG, '登录引导防抖,忽略重复点击')
return
}
lastNavAt = now
const query = options.redirect ? `?redirect=${encodeURIComponent(options.redirect)}` : ''
logger.info(LOG, '引导进入登录页, redirect=', options.redirect || '')
wx.navigateTo({
url: `/pages/login/login${query}`,
fail: (e) => {
// 页面栈过深或跳转被占用时降级 redirectTo,保证受限操作一定有出口
logger.warn(LOG, 'navigateTo 登录页失败,降级 redirectTo, err=', e && e.errMsg)
wx.redirectTo({
url: `/pages/login/login${query}`,
fail: (err) => logger.warn(LOG, 'redirectTo 登录页失败, err=', err && err.errMsg),
})
},
})
}