import { getWechatConfig } from '@/api/wechat' /** * 微信订阅消息工具类 * 统一管理订阅消息相关功能 */ class SubscribeManager { constructor() { this.wechatConfig = { taskNotifyTemplateId: '' } this.configLoaded = false } /** * 加载微信配置 * @returns {Promise} */ loadWechatConfig() { return new Promise((resolve, reject) => { if (this.configLoaded && this.wechatConfig.taskNotifyTemplateId) { resolve(this.wechatConfig) return } getWechatConfig() .then((response) => { if (response.code === 200 && response.data) { this.wechatConfig = response.data this.configLoaded = true console.log('微信配置加载成功:', this.wechatConfig) resolve(this.wechatConfig) } else { console.warn('加载微信配置失败,使用默认配置') reject(new Error('加载微信配置失败')) } }) .catch((error) => { console.error('加载微信配置失败:', error) reject(error) }) }) } /** * 检查本地订阅状态(从缓存读取) * @returns {boolean} */ checkLocalSubscribeStatus() { return uni.getStorageSync('hasSubscribedTaskNotify') || false } /** * 检查微信官方订阅状态(真实状态) * @returns {Promise} */ checkWechatSubscribeStatus() { return new Promise((resolve) => { // #ifdef MP-WEIXIN // 需要先加载配置获取模板ID this.loadWechatConfig() .then(() => { const templateId = this.wechatConfig.taskNotifyTemplateId if (!templateId) { console.warn('模板ID未配置,无法检查订阅状态') resolve(false) return } wx.getSetting({ withSubscriptions: true, success: (res) => { // console.log('微信订阅状态查询结果:', res.subscriptionsSetting.mainSwitch) // 检查subscriptionsSetting中是否有该模板ID的记录 if (res.subscriptionsSetting && res.subscriptionsSetting.mainSwitch) { resolve(false); // 如果用户同意了订阅,则返回false // const subscribeStatus = res.subscriptionsSetting.mainSwitch; // console.log(res.subscriptionsSetting.itemSettings[templateId]) // resolve(subscribeStatus) // 'accept' 表示用户同意订阅,'reject' 表示拒绝,'ban' 表示被封禁 // const isSubscribed = subscribeStatus === 'accept' // console.log(`模板ID ${templateId} 订阅状态:`, subscribeStatus, '是否已订阅:', isSubscribed) // resolve(isSubscribed) // console.log("发起订阅请求") // wx.requestSubscribeMessage({ // tmplIds: [templateId], // success: (res) => { // console.log('订阅消息状态:', res) // if (res[templateId] === 'accept') { // console.log('用户已订阅') // resolve(true) // } else if (res[templateId] === 'reject') { // console.log('用户已拒绝订阅') // resolve(false) // } else if (res[templateId] === 'ban') { // console.log('用户已封禁订阅') // resolve(false) // } else { // console.log('未知订阅状态') // resolve(false) // } // },fail: (err) => { // console.error('订阅消息失败:', err) // resolve(false) // } // } // ) } else { console.log('未找到订阅设置信息,视为未订阅') resolve(false) } }, fail: (err) => { console.error('获取微信设置失败:', err) resolve(false) } }) }) .catch((error) => { console.error('加载配置失败,无法检查订阅状态:', error) resolve(false) }) // #endif // #ifndef MP-WEIXIN console.log('非微信小程序环境,无法检查订阅状态') resolve(false) // #endif }) } /** * 检查订阅状态(综合检查) * 先检查本地状态,再检查微信官方状态 * @returns {Promise<{local: boolean, wechat: boolean, needResubscribe: boolean}>} */ async checkSubscribeStatus() { const localStatus = this.checkLocalSubscribeStatus() const wechatStatus = await this.checkWechatSubscribeStatus() // 如果本地显示已订阅,但微信官方显示未订阅,需要重新订阅 const needResubscribe = !localStatus if (needResubscribe) { // console.warn('本地状态与微信官方状态不一致,需要重新订阅') // 清除本地记录 // uni.removeStorageSync('hasSubscribedTaskNotify') } return { local: localStatus, wechat: wechatStatus, needResubscribe: needResubscribe, isSubscribed: wechatStatus // 以微信官方状态为准 } } /** * 显示订阅确认弹窗 * @returns {Promise} */ showSubscribeConfirm() { return new Promise((resolve, reject) => { // #ifdef MP-WEIXIN wx.showModal({ title: '开启任务通知', content: '勾选「总是保持以上选择」,后续新任务将自动推送~', confirmText: '去开启', cancelText: '暂不开启', success(res) { if (res.confirm) { resolve() } else { reject(new Error('用户取消')) } }, fail() { reject(new Error('弹窗失败')) } }) // #endif // #ifndef MP-WEIXIN uni.showToast({ title: '仅支持微信小程序', icon: 'none' }) reject(new Error('仅支持微信小程序')) // #endif }) } /** * 订阅任务通知 * @param {Object} options 配置选项 * @param {boolean} options.showConfirm 是否显示确认弹窗,默认true * @param {Function} options.onSuccess 成功回调 * @param {Function} options.onReject 拒绝回调 * @param {Function} options.onFail 失败回调 * @returns {Promise} */ async subscribeTaskNotify(options = {}) { const { showConfirm = true, onSuccess, onReject, onFail } = options try { // 加载配置 await this.loadWechatConfig() // 检查配置是否加载 if (!this.wechatConfig.taskNotifyTemplateId) { uni.showToast({ title: '配置加载中,请稍后重试', icon: 'none' }) throw new Error('配置未加载') } // 显示确认弹窗(如果需要) if (showConfirm) { await this.showSubscribeConfirm() } // 发起订阅 return new Promise((resolve, reject) => { // #ifdef MP-WEIXIN wx.requestSubscribeMessage({ tmplIds: [this.wechatConfig.taskNotifyTemplateId], success: (res) => { console.log('订阅消息授权结果:', res) const templateId = this.wechatConfig.taskNotifyTemplateId if (res[templateId] === 'accept') { // 记录已订阅 uni.setStorageSync('hasSubscribedTaskNotify', true) uni.showToast({ title: '订阅成功', icon: 'success' }) if (onSuccess) onSuccess() resolve({ success: true, action: 'accept' }) } else if (res[templateId] === 'reject') { uni.showToast({ title: '您拒绝了订阅', icon: 'none' }) if (onReject) onReject() resolve({ success: false, action: 'reject' }) } else { // 其他情况(ban等) resolve({ success: false, action: res[templateId] }) } }, fail: (err) => { console.error('订阅消息失败:', err) uni.showToast({ title: '订阅失败', icon: 'none' }) if (onFail) onFail(err) reject(err) } }) // #endif // #ifndef MP-WEIXIN uni.showToast({ title: '仅支持微信小程序', icon: 'none' }) reject(new Error('仅支持微信小程序')) // #endif }) } catch (error) { console.error('订阅流程异常:', error) throw error } } /** * 快速订阅(带确认弹窗) * @returns {Promise} */ subscribeWithConfirm() { return this.subscribeTaskNotify({ showConfirm: true }) } /** * 直接订阅(不显示确认弹窗) * @returns {Promise} */ subscribeDirect() { return this.subscribeTaskNotify({ showConfirm: false }) } /** * 自动订阅(智能检查) * 如果已订阅则跳过,未订阅则显示确认弹窗 * @param {Object} options 配置选项 * @param {boolean} options.force 是否强制显示订阅弹窗,默认false * @returns {Promise} */ async autoSubscribe(options = {}) { const { force = false } = options try { // 综合检查订阅状态(本地 + 微信官方) const status = await this.checkSubscribeStatus() console.log('订阅状态检查结果:', status) // 如果微信官方状态显示已订阅,且不强制订阅 if (status.isSubscribed && !force) { console.log('用户已订阅过(微信官方状态),跳过自动订阅') return { success: true, action: 'already_subscribed', skipped: true, status } } // 如果需要重新订阅或未订阅 if (status.needResubscribe) { console.log('检测到订阅状态失效,触发重新订阅流程') } else { console.log('用户未订阅,触发自动订阅流程') return { success: false, action: 'not_subscribed', skipped: true, status } } // 显示确认弹窗并订阅 直接默认订阅 const result = await this.subscribeWithConfirm(); return { ...result, status } } catch (error) { console.log('自动订阅流程异常:', error) return { success: false, action: 'error', error } } } /** * 重置订阅状态 */ resetSubscribeStatus() { uni.removeStorageSync('hasSubscribedTaskNotify') } } // 创建单例 const subscribeManager = new SubscribeManager() export default subscribeManager