Files
im/util/index.js
T
2025-12-27 07:08:30 +08:00

397 lines
10 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//import i18n from '@/locales'
import base from '@/common/config';
//import store from "@/store";
import IMSDK from "openim-uniapp-polyfill";
import md5 from "md5";
import {downloadFile} from "@/uni_modules/network-manage";
const isString = (v)=> {
return typeof v === 'string' || v instanceof String;
},
isNumber=(v) =>{
return typeof v === 'number' && !isNaN(v);
},
isInteger=(v) =>{
return typeof v === 'number' && isFinite(v) && Math.floor(v) === v;
},
isBoolean=(v) =>{
return typeof v === 'boolean';
},
isArray=(v) =>{
return Array.isArray(v);
},
isObject=(v) =>{
return v !== null && typeof v === 'object' && !Array.isArray(v);
},
isFunction=(v) =>{
return typeof v === 'function';
},
isNull=(v) =>{
return v === null;
},
isUndefined=(v) =>{
return typeof v === 'undefined';
},
isSymbol=(v) =>{
return typeof v === 'symbol';
},
isDate=(v) =>{
return Object.prototype.toString.call(v) === '[object Date]';
},
isRegExp=(v) =>{
return Object.prototype.toString.call(v) === '[object RegExp]';
},
isError=(v) =>{
return v instanceof Error;
},
isMap=(v) =>{
return v instanceof Map;
},
isSet=(v) =>{
return v instanceof Set;
},
isWeakMap=(v) =>{
return v instanceof WeakMap;
},
isWeakSet=(v) => {
return v instanceof WeakSet;
},
_goto = (url,type) => {
//console.log(url);
type = type || '0'; //0 navigateTo 1 redirectTo
if(url){
if(isInteger(url)){
uni.navigateBack({
delta:url,
})
}else{
url+="";
if(url.substr(0,6) != '/pages'){
url='/pages'+url
}
if(type == '1'){
return uni.redirectTo({
url:url
});
}
if(type == '2'){
return uni.switchTab({
url:url
});
}
uni.navigateTo({
url:url
})
}
}
};
const showToast = (msg,url,icon) => {
//msg = i18n.t(msg);
// #ifdef APP
plus.nativeUI.closeToast();
plus.nativeUI.toast(msg,{
align:'center',
verticalAlign:"center",
style:"inline",
icon:icon=='error' ? '/static/img/common/error.png' : '/static/img/common/success.png',
iconWidth:24,
iconHeight:24
});
if(url){
setTimeout(()=>{
_goto(url);
},3000)
}
// #endif
// #ifndef APP
uni.showToast({
//image:icon=='error' ? '/static/img/common/error.png' : '/static/img/common/success.png',
icon:icon=='error' ? icon : 'success',
title:msg,
showToast:3000,
complete:()=>{
if(url){
setTimeout(()=>{
_goto(url);
},3000)
}
}
});
// #endif
}
const error = (msg,url) => {
showToast(msg,url,'error');
}
const success = (msg,url) => {
showToast(msg,url,'success');
}
const scan = ()=>{
uni.scanCode({
success(res){
/**
* result 所扫码的内容
scanType 所扫码的类型 App、微信小程序、百度小程序、QQ小程序、京东小程序、支付宝小程序
charSet 所扫码的字符集 App、微信小程序、百度小程序(所扫码的字符集,仅支持 Android 系统)、QQ小程序、京东小程序
path 当所扫的码为当前应用的合法二维码时,会返回此字段,内容为二维码携带的 path。 微信小程序、QQ小程序、京东小程序
rawData 原始数据,base64 编码 微信小程序、QQ小程序、京东小程序、支付宝小程序
code 扫码所得数据 支付宝小程序
qrCode 扫描二维码时返回二维码数据 支付宝小程序
barCode 扫描条形码时返回条形码数据 支付宝小程序
imageChannel 来源 支付宝小程序
*/
if(res.result){
if(res.result.indexOf('blackcatp:/')){
uni.navigateTo({
url:res.result.substring(11)
})
}else{
success(res.result)
}
}
},
fail(res){
},
complete(res){
console.log(res)
}
});
}
const fileExsit = async(fn)=>{
return await new Promise((resolve) => {
plus.io.resolveLocalFileSystemURL(fn, function(entry) {
resolve(true);
}, function() {
resolve(false);
});
})
}
const downloadFile1 = (url, savepath, successCb, errorCb, progressCb) => {
const root_dir = "_doc/";
if (!url) {
errorCb && errorCb.call(this,new Error('empty url'));
return;
}
const startDownload = () => {
console.log(33333333333333,root_dir+savepath);
const task = plus.downloader.createDownload(url, { filename: root_dir+savepath, timeout: 2 }, function(d, status) {
console.log('completedCB');
console.log(d);
console.log(status);
if (status === 200) {
const local = d && d.filename ? d.filename : root_dir+savepath;
successCb && successCb.call(this,local);
} else {
errorCb && errorCb.call(this,new Error('download status ' + status));
}
});
task.addEventListener('statechanged', function(t, status) {
console.log('statechanged',d,status);
if (t.state === 3) {
var downloaded = t.downloadedSize || t.downloaded || 0;
var total = t.totalSize || t.total || 0;
var prog = 0;
if (total > 0) prog = Math.min(100, Math.floor(downloaded / total * 100));
progressCb && progressCb.call(this,prog);
}
});
try{
task.start();
plus.downloader.startAll();
}catch(e){
console.log('e',e);
}
plus.downloader.enumerate((downloads )=>{
for(var i =0;i<downloads.length;i++){
//downloads[i].abort();
console.log(downloads[i]);
}
})
};
// 目录不存在,尝试创建(针对 _doc/<conversationID> 结构)
const fns = savepath.split('/');
plus.io.requestFileSystem(plus.io.PRIVATE_DOC, function(fs) {
fs.root.getDirectory(fns[0], { create: true }, function(entry) {
startDownload();
}, function(e) {
// 创建失败也尝试下载,可能运行时会自动创建
startDownload();
});
}, function(e) {
startDownload();
});
}
const get_absolute_path = (fn)=>{
return plus.io.convertLocalFileSystemURL(fn);
}
const pendingDownloads = new Map();
const cacheFile = (url, saveDir,progressCallback) => {
let cacheDir = plus.io.convertLocalFileSystemURL(`_doc/{{dir}}/{{key}}.{{ext}}`);
cacheDir = cacheDir.replace('apps/'+plus.runtime.appid+'/doc','cache');
return new Promise(async (resolve, reject) => {
try {
if(!url || !url.startsWith('http')){
resolve(url);
return;
}
const key = md5(url);
var ext = "png"
if(url.toLowerCase().indexOf('.mp4')!==-1){
ext = "mp4";
}
const cacheFilePath = cacheDir.replace('{{dir}}',saveDir)
.replace('{{key}}',key)
.replace('{{ext}}',ext);
//console.error('cacheDir:',cacheDir);
// 如果缓存存在且文件存在,直接返回缓存路径
if (cacheFilePath) {
//console.error('cacheFilePath:', cacheFilePath);
const coverExists = await fileExsit(cacheFilePath);
//console.log("coverExists" ,coverExists);
if (coverExists) {
//console.log("已缓存为:" , cacheFilePath,url);
resolve(cacheFilePath);
return;
}
}
// 2. 检查是否已经有相同的 URL 正在下载
if (pendingDownloads.has(url)) {
// 如果已经有相同的下载在进行,则添加到等待列表
pendingDownloads.get(url).promises.push({ resolve, reject });
return;
}
// 3. 如果没有正在下载,则创建新的下载任务
pendingDownloads.set(url, {
promises: [{ resolve, reject }],
completed: false,
savedPath: saveDir
});
// 4. 开始下载文件
const task = downloadFile({
url:url,
timeout: 30000,
filePath:cacheFilePath,
success(res) {
// 下载成功,解决所有等待的 Promise
const info = pendingDownloads.get(url);
if (info) {
info.completed = true;
info.promises.forEach(p => p.resolve(res.tempFilePath));
pendingDownloads.delete(url);
}
},
fail(e){
// 下载失败,拒绝所有等待的 Promise
const info = pendingDownloads.get(url);
if (info) {
info.promises.forEach(p => p.reject(error));
pendingDownloads.delete(url);
}
},
complate(){
task = null;
}
});
//console.error('task:', task);
task.onProgressUpdate(({progress,totalBytesWritten,totalBytesExpectedToWrite})=>{
//console.error('pres:', progress,totalBytesWritten,totalBytesExpectedToWrite);
progressCallback && progressCallback.call(this,progress,totalBytesWritten,totalBytesExpectedToWrite)
});
} catch (error) {
console.error('cacheFile 发生错误:', error);
resolve(url); // 返回原始URL作为fallback
}
});
};
export default{
cacheFile,
fileExsit,
get_absolute_path,
downloadFile,
isString :isString,
isNumber :isNumber,
isInteger :isInteger,
isBoolean :isBoolean,
isArray :isArray,
isObject :isObject,
isFunction :isFunction,
isNull :isNull,
isUndefined :isUndefined,
isSymbol :isSymbol,
isDate :isDate,
isRegExp :isRegExp,
isError :isError,
isMap :isMap,
isSet :isSet,
isWeakMap :isWeakMap,
isWeakSet :isWeakSet,
cdn(v){
v= v || "";
v = v.replace(/\\/ig,"/").replace('/\/\/ig',"/");
//console.log(v);
if(v && isString(v)){
if(v.startsWith('//')){
return 'http:'+v;
}
if(v.startsWith('blob:') || v.startsWith('file://') || v.startsWith('http')){
return v;
}
v= v.startsWith('/') ? v : '/'+v;
return base.cdnUrl+''+v;
}
return "";
},
"goto":_goto,
showToast,
error,
success,
scan,
copy(v){
let that = this;
uni.setClipboardData({
data:v+'',
success() {
that.success('复制成功');
}
})
},
toDate(time) {
var date = new Date(time * 1000);
var fmt = 'yyyy-MM-dd hh:mm:ss';
var o = {
'M+': date.getMonth() + 1, //月份
'd+': date.getDate(), //日
'h+': date.getHours(), //小时
'm+': date.getMinutes(), //分
's+': date.getSeconds(), //秒
'q+': Math.floor((date.getMonth() + 3) / 3), //季度
S: date.getMilliseconds() //毫秒
};
if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
for (var k in o) if (new RegExp('(' + k + ')').test(fmt)) fmt = fmt.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length));
return fmt;
},
formatAmount(v,wei){
if(!v){return 0.00;}
v=v+"";
v = parseFloat(v).toFixed(wei || 2);
return parseFloat(v);
},
imapi(method,data){
return IMSDK.asyncApi(method,IMSDK.uuid(),data);
}
}