wlzboy
8 小时以前 10354e63eb3298beb9ebcc029dd9f48d8936a272
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
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<boolean>}
   */
  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