export function formatDate(date, fmt) { const o = { 'M+': date.getMonth() + 1, // 月份 'd+': date.getDate(), // 日 'h+': date.getHours(), // 小时 'm+': date.getMinutes(), // 分 's+': date.getSeconds(), // 秒 S: date.getMilliseconds() // 毫秒 }; if (/(y+)/.test(fmt)) { // eslint-disable-next-line no-param-reassign fmt = fmt.replace(RegExp.$1, `${date.getFullYear()}`.substr(4 - RegExp.$1.length)); } for (const k in o) { if (new RegExp(`(${k})`).test(fmt)) { // eslint-disable-next-line no-param-reassign fmt = fmt.replace(RegExp.$1, RegExp.$1.length === 1 ? o[k] : `00${o[k]}`.substr(`${o[k]}`.length)); } } return fmt; } export function copyText(text) { uni.setClipboardData({ data: text, success: () => { uni.showToast({ title: '复制成功', icon: 'none' }); }, fail: (err) => { uni.showToast({ title: '复制失败', icon: 'none' }); } }); }; export const removeFile = (filePath) => { plus.io.resolveLocalFileSystemURL( filePath, (entry) => { entry.remove( () => console.log("删除成功"), // 成功回调 (error) => console.log(`删除失败:${error.message}`) // 失败回调 ); }, (error) => console.log(`文件不存在:${error.message}`) ); } export const base64ToFile = (base64Strs, fileName, callback) => { let index = base64Strs.indexOf(','); let base64Str = base64Strs.slice(index + 1, base64Strs.length); plus.io.requestFileSystem(plus.io.PRIVATE_DOC, function(fs) { fs.root.getFile(fileName, { create: true }, function(entry) { let fullPath = entry.fullPath; let platform = uni.getSystemInfoSync().platform; if (platform == 'android') { let Base64 = plus.android.importClass("android.util.Base64"); let FileOutputStream = plus.android.importClass("java.io.FileOutputStream"); try { let out = new FileOutputStream(fullPath); let bytes = Base64.decode(base64Str, Base64.DEFAULT); out.write(bytes); out.close(); callback && callback(entry.toLocalURL()); } catch (e) { console.log(e.message); } } else if (platform == 'ios') { let NSData = plus.ios.importClass('NSData'); let nsData = new NSData(); nsData = nsData.initWithBase64EncodedStringoptions(base64Str, 0); if (nsData) { nsData.plusCallMethod({ writeToFile: fullPath, atomically: true }); plus.ios.deleteObject(nsData); } callback && callback(entry.toLocalURL()); } }); }); }; export function textToSpeech(text, options = {}) { return new Promise((resolve, reject) => { const { token = '24.1c8cc30b5f7be445723b6d4b19a36152.2592000.1765094496.282335-120706844', tex = text, cuid = 'uni-app-demo', ctp = 1, lan = 'zh', spd = 5, pit = 5, vol = 5, per = 0 } = options const url = 'https://tsn.baidu.com/text2audio' const params = { tex: encodeURIComponent(tex), cuid, ctp, lan, spd, pit, vol, per, tok: token } // 构建查询字符串 const queryString = Object.keys(params).map(key => { return `${key}=${params[key]}` }).join('&') uni.request({ url: `${url}?${queryString}`, method: 'GET', responseType: 'arraybuffer', success: (res) => { // 检查响应状态 if (res.statusCode === 200) { // 检查是否是音频数据(MP3格式通常以特定字节开头) if (res.data && res.data.byteLength > 0) { // 检查是否是JSON错误响应(百度API错误时返回JSON) try { const textDecoder = new TextDecoder('utf-8') const text = textDecoder.decode(new Uint8Array(res.data.slice(0, 100))) if (text.startsWith('{') || text.startsWith('[')) { // 是JSON响应,说明是错误 const errorData = JSON.parse(text) console.error('TTS API Error:', errorData) reject(new Error(errorData.err_msg || 'TTS请求失败')) return } } catch (e) { // 不是JSON,应该是音频数据 } resolve(res.data) } else { reject(new Error('返回数据为空')) } } else { reject(new Error(`请求失败,状态码: ${res.statusCode}`)) } }, fail: (err) => { console.error('TTS Request Error:', err) reject(new Error(err.errMsg || '网络请求失败')) } }) }) }