//app.js App({ async onLaunch () { this.login(); // 移除 2022-12-05 之前的本地存储,因为可能有敏感词存在 const timestamp = new Date('2022-12-05').getTime(); const audioList = this.globalData.getAudioList().filter(v => v.time > timestamp); const storageKey = 'audioList'; wx.setStorageSync(storageKey, audioList); }, // 将登录态封装进去 // todo: 多个请求同时发起,且登录态都失效时,ssid 会相互覆盖 async request(config){ let ssid = wx.getStorageSync('ssid'); if(!ssid){ ssid = await this.login(); } const initialSuccess = config.success; config.data = { ...config.data, ssid }; config.success = async resp => { if(resp.data.code === 5001000){ wx.setStorageSync('ssid', ''); delete config.ssid; this.request(config); } else{ initialSuccess(resp); } }; config = { header: { 'content-type': 'application/json' }, dataType: 'json', method: 'POST', ...config }; return wx.request(config); }, login(){ let ssid = wx.getStorageSync('ssid'); if(ssid){ return ssid; } wx.showLoading({ title: '登录中...', mask: true }); return new Promise((resolve, reject) => { wx.login({ success: res => { wx.request({ url: `${this.globalData.domain}/open-api/mp/login`, data: { code: res.code, appid: 'wx330e54aa6000516d' }, header: { 'content-type': 'application/json' }, dataType: 'json', method: 'POST', success: resp => { const { ssid, openid } = resp.data?.data?.user; wx.setStorageSync('ssid', ssid); wx.setStorageSync('openid', openid); resolve(ssid); }, fail: resp => { wx.showModal({ title: '提示', content: '登录失败,点击确定重试', showCancel: false, success: res => { this.login(); } }); reject(resp.errMsg); }, complete: () => { wx.hideLoading(); } }); } }); }); }, globalData: { // domain: 'http://localhost:3003', domain: 'https://api.xwenliang.cn', getTypeList(){ const globalData = this; return [ { desc: 'Chelsie(女)', voice: 'Chelsie', async createUrl(text){ return await globalData.requestTTS(text, 'Chelsie'); } }, { desc: 'Cherry(女)', voice: 'Cherry', async createUrl(text){ return await globalData.requestTTS(text, 'Cherry'); } }, { desc: 'Ethan(男)', voice: 'Ethan', async createUrl(text){ return await globalData.requestTTS(text, 'Ethan'); } }, { desc: 'Serena(女)', voice: 'Serena', async createUrl(text){ return await globalData.requestTTS(text, 'Serena'); } }, { desc: 'Dylan(北京话-男)', voice: 'Dylan', async createUrl(text){ return await globalData.requestTTS(text, 'Dylan'); } }, { desc: 'Jada(吴语-女)', voice: 'Jada', async createUrl(text){ return await globalData.requestTTS(text, 'Jada'); } }, { desc: 'Sunny(四川话-女)', voice: 'Sunny', async createUrl(text){ return await globalData.requestTTS(text, 'Sunny'); } } ]; }, // TTS接口请求方法 async requestTTS(text, voice) { return new Promise((resolve, reject) => { const app = getApp(); app.request({ url: `${this.domain}/open-api/wx330e54aa6000516d/tts`, data: { text, voice }, success: (resp) => { if (resp.data.code === 2000000) { resolve(resp.data.data.url); } else { wx.showToast({ title: resp.data.msg || '生成失败', icon: 'none' }); reject(new Error(resp.data.msg || '生成失败')); } }, fail: (error) => { wx.showToast({ title: '网络错误', icon: 'none' }); reject(error); } }); }); }, getSelectedTypeIndex(){ const storageKey = 'audioTypeselectedIndex'; return wx.getStorageSync(storageKey); }, setSelectedTypeIndex(index){ const storageKey = 'audioTypeselectedIndex'; wx.setStorageSync(storageKey, index); return index; }, getAudioList(){ const storageKey = 'audioList'; return wx.getStorageSync(storageKey) || []; }, /** * @param {(add|delete)} action - 增或删 * @param {object|number} [param] - 增加时是 audio 描述,删除时是唯一特征 path 值 */ setAudioList(action, param){ const storageKey = 'audioList'; const list = this.getAudioList() || []; if(action === 'add' && param.constructor === Object){ list.push(param); wx.setStorageSync(storageKey, list); } if(action === 'delete' && String(param)){ const index = list.findIndex(v => v.path === param); if(index > -1){ list.splice(index, 1); wx.setStorageSync(storageKey, list); } } return list; } } });