c5_labsci/fapp/ciyon_ap/util/ciy.js
2026-01-29 21:27:08 +08:00

2617 lines
73 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.

/*
=================================================================================
* License: GPL-2.0 license
* Author: 众产® https://ciy.cn/code
* Version: 0.1.16
=================================================================================
app函数库
* alert (await)默认alert
* toast (await)默认提示
* getpage 获取当前/上页页面
* setuserstorage 保存用户信息、字典缓存、积分埋点
* appupdate APP自动更新
* connectbt 连接蓝牙
* CiyWebSocket websocket客户端类
app&page函数库
* getme 获取本地me缓存
* callfunc (await)服务端ajax请求
* lang 多语言
* uperr 错误捕获处理
* json_parse 字符串转json
* json_string json转字符串
* getstorage 读取storage
* setstorage 写入storage
* clearstorage 清空所有storage
* removestorage 删除storage
page函数库
* gourl 页面跳转。支持 http[web]、![原型]、*[alert提示]、$[需登录常规url]、常规url
* goweb 带授权的打开H5页面
* goloc 按经纬度打开地图
* gophone 拨打电话
* goani 持续生成动画
* copyboard 拷贝文本
* isfloat0 校验float是否0
* isarray 判断变量是否array
* isobject 判断变量是否object
* islocalmedia 判断文件名是否本地文件
* isimg 是否图片
* isvideo 是否视频
* file_ext 获取文件扩展名
* file_stor ud url转绝对url
* hasstr 字符串是否包含另一个字符串
* ccode 以id查询字典中的值
* scode 以ids查询字典中的多个name
* mcode 以id查询字典中的多级name
* bcode 以int查询字典中的多个name
* enbase64 base64编码
* svg2bg 将svg转成backgroundImage语法
* topad0 数字前面补0
* tonumtho 整数部分千分位显示
* tonumdec 小数部分
* tostr 转字符串
* toint 转整数
* tofloat 转小数
* tostamp 转时间戳
* todatetime 时间戳转日期时间
* tofix 处理小数显示
* tounit 显示多级单位
* tocyc 显示周期 月/天/分钟
* tomsk 显示文字遮罩
* totimespan 将时间转成 xx天后/xx小时前
* totimesec 将秒数转成 xx天/xx小时
* totimepoint 将数字转成 xx:xx[:xx]
* todayage 返回日龄天数
* tobr 将\n替换成<br/>,将<>替换成可显示
* pagenoscroll 页面滚动控制
* settheme 设置暗黑模式
* setfont 设置敬老模式
* executepnt 触发积分埋点
* setTabbar 设置Tabbar
* getauth (await)获取用户信息未登录调起登录界面填充me/g
* scanqr (await)扫二维码
* popmenu (await)弹出上拉菜单
* toast (await)提示
* alert (await)alert弹出框
* askmsg (await)询问弹出框
* inputmsg (await)输入弹出框
* sleep (await)延迟毫秒
* load_ciydict (await)获取远程静态dict
* load_svgicon (await)获取远程静态svgicon
* shareparam 分享链接转换
* getstrparam 解析简易参数
* urlparam 解析url
* arrayfind 从数组中匹配值。返回index
* objdeepmerge object合并自动避开静态字典自动处理带id数组
* objtolist 将object并入list数组
* objclone 深度复制obj
* str2date 字符串转Date
* bin2hex bin转hex字符串
* hex2bin hex字符串转bin
* style2obj 将style属性转成object
* nopower 权限检查
* getroute 获取route
* com_getpage 组件中获取页面句柄
* com_gethdft (await)组件中获取页面标题栏/导航栏高度
* getrefs (await)稳定获取ref
* getrefsSync 确保已加载com的同步函数
* getrect (await)获取元素尺寸
* file_upload1 (await)上传单个文件返回url
* file_uploads (await)上传多个文件
* go/goe (await)golang式异步错误处理
page生命周期函数
* onLoad 页面初始化。存储upid构建post
* onShow 页面显示调用。设置暗黑主题/敬老字体
* onPageScroll 页面滚动事件。scrollcbs传递函数引用
page默认数据
* init 初始交互数据
* srv 默认微服务指向
* opn 页面urlget参数
* me 用户状态
* g 用户及字典数据引用
* pagedata 页面间数据传递 替代vuex\Pinia
* jsnurl 指向动态服务器(多个)。默认t
* header_* 页面边角尺寸
* footer_* 页面边角尺寸
*/
export default {
install(ap, app) {
ap.config.globalProperties._proptest = () => {}; //代码受限
ap.directive('swipe', { //微信小程序暂时无法使用app/h5支持
mounted: function(el, binding) {
console.log('wx?', el, binding);
}
});
app.methods.launch = function() {
var app = this;
// #ifdef MP-WEIXIN
var sys_system = wx.getSystemSetting();
var sys_window = wx.getWindowInfo();
var sys_appinfo = wx.getAppBaseInfo();
var sys_appauth = wx.getAppAuthorizeSetting();
var sys_device = wx.getDeviceInfo();
console.log('sys_system', sys_system);
console.log('sys_window', sys_window);
console.log('sys_appinfo', sys_appinfo);
console.log('sys_appauth', sys_appauth);
console.log('sys_device', sys_device);
var sys = {
...sys_system,
...sys_window,
...sys_appinfo,
...sys_appauth,
...sys_device
};
if (!sys.screenHeight) {
sys = uni.getSystemInfoSync();
console.log('getSystemInfoSync', sys);
}
// #endif
// #ifndef MP-WEIXIN
var sys = uni.getSystemInfoSync();
// #endif
app.globalData._sysinfo = sys;
app.globalData.ciy_page_data = {};
app.globalData._header_statusbar_height = sys.statusBarHeight;
if (sys.safeAreaInsets)
app.globalData._footer_safe_height = sys.safeAreaInsets.bottom;
else if (sys.safeArea)
app.globalData._footer_safe_height = sys.screenHeight - sys.safeArea.bottom;
else
app.globalData._footer_safe_height = 0;
app.globalData._header_title_height = 40;
app.globalData._header_title_margin = 0;
// #ifdef MP-WEIXIN
var menubtn = wx.getMenuButtonBoundingClientRect();
console.log('menubtn', menubtn);
app.globalData._menubtn = menubtn;
app.globalData._header_title_margin = sys.screenWidth - menubtn.left;
app.globalData._header_title_height = (menubtn.top - sys.statusBarHeight) * 2 + menubtn.height;
try {
app.globalData.plugin_wechatsi = requirePlugin("WechatSI");
app.globalData.plugin_wechatsi_manager = app.globalData.plugin_wechatsi.getRecordRecognitionManager();
} catch (e) {
console.log('err', e);
}
// #endif
};
app.methods.lang = function(str) {
var app = this;
if (typeof(app.$t) == 'function')
return app.$t(str);
return str;
};
app.methods.alert = async function(content) {
return new Promise((resolve, reject) => {
var opt = {
content: content,
showCancel: false
};
opt.success = res => {
resolve(true);
};
uni.showModal(opt);
}).catch(e => {
return e;
});
};
app.methods.toast = async function(content, icon) {
return new Promise((resolve, reject) => {
if (typeof(icon) === 'function') {
cb = icon;
icon = 'none';
}
if (!icon)
icon = 'none';
uni.showToast({
title: content,
icon: icon
});
setTimeout(function() {
resolve();
}, 2000);
}).catch(e => {
return e;
});
};
app.methods.getpage = function(idx) { //idx 0当前页1上一页
var ps = getCurrentPages();
var p = null;
idx = idx || 0;
if (idx == 1) {
if (ps.length == 1)
return null;
p = ps[ps.length - 2];
} else {
p = ps[ps.length - 1];
}
// #ifdef MP-WEIXIN
p = p.$vm;
// #endif
return p;
};
app.methods.getme = function() {
var me = this.getstorage("me");
if (!me)
return {
id: 0
};
return me;
};
app.methods.uperr = function(type, msg) {
console.warn('uperr', type, msg);
var errdata = {};
errdata.type = type;
errdata.t = parseInt(new Date().getTime() / 1000);
errdata.msg = '';
if (typeof(msg) == 'object')
errdata.msg = this.json_string(msg);
else
errdata.msg = msg + '';
this.globalData.errdata.push(errdata);
this.setstorage('err', this.globalData.errdata);
};
app.methods.json_parse = function(data) {
try {
if (data.length > 0 && data[0] != '[' && data[0] != '{') {
var ind = data.indexOf('{');
if (ind == -1)
return null;
if (ind > 0)
data = data.substring(ind);
}
return JSON.parse(data);
} catch (e) {
console.error('json_parse', e);
}
return null;
};
app.methods.json_string = function(data) {
try {
return JSON.stringify(data);
} catch (e) {
console.error('json_string', e);
}
return '';
};
app.methods.callfunc = async function(opt) {
//成功{code:1,...}
//失败{errmsg:'错误信息'}
//func
//data = null 无post数据GET方法
//catch=0 不缓存,>0缓存
//loadhide=true 默认false取消加载中显示 loadtxt
var app = this;
return new Promise((resolve, reject) => {
opt = opt || {};
if (opt.func.substring(0, 4) == 'http')
url = opt.func;
else {
opt.srv = opt.srv || app.globalData.srv;
var url = app.globalData.jsnurl[opt.srv];
if (!url)
return reject({
errmsg: 'srv无法匹配:' + opt.srv
});
if (opt.func.indexOf('?') > -1)
url += opt.func;
else
url += app.globalData.jsnajax + opt.func;
}
opt.cache = opt.cache || 0; // 0不缓存 >0 对比时间,是否请求
if (opt.cache > 0) {
if (!opt.cachekey) {
opt.cachekey = 'f_' + opt.func;
for (var i in opt.data) {
if (i == 'once' || i == '_pf')
continue;
if (typeof(opt.data[i]) === 'object')
continue;
opt.cachekey += '_' + i.substring(0, 1) + opt.data[i];
}
}
if (opt.cache > 1) {
var dat = app.getstorage(opt.cachekey);
var t = new Date().getTime() - (typeof(dat) == 'object' ? dat.t : 0);
if (t < opt.cache * 1000) {
if (opt.pagethis && opt.pagethis._stopPullDown) {
opt.pagethis._stopPullDown = false;
uni.stopPullDownRefresh();
}
return resolve(dat.d);
}
}
}
if (!opt.loadhide) {
opt._showload = setTimeout(function() {
opt._showloaded = true;
uni.showToast({
title: opt.loadtxt || '加载中',
icon: 'loading',
duration: 3000,
mask: true
});
}, 500);
}
var header = {};
opt.data = opt.data || {};
if (app.globalData._wxappid)
opt.data._appid = app.globalData._wxappid;
if (opt.pagethis)
opt.data = Object.assign({}, opt.pagethis.opn, opt.data);
const makeRequest = () => {
header['ciyauth'] = app.getstorage("_" + app.globalData.tokenfield);
opt.data._pf = 'MB' + new Date().getTime() + '_' + parseInt(80000000 + Math.random() * 10000000);
uni.request({
url: url,
data: opt.data,
withCredentials: true,
dataType: 'text',
method: opt.data ? 'POST' : 'GET',
header: header,
fail: res => {
var errmsg = res.errMsg || 'nofind errMsg.';
if (errmsg.indexOf('fail abort') > 0)
errmsg = '网络信号不好';
else if (errmsg.indexOf('equest:fail timeout') > 0)
errmsg = '网络访问超时';
else if (errmsg.indexOf('equest:fail') > 0)
errmsg = '网络不可用';
return reject({
errmsg: errmsg
});
},
complete: res => {
if (opt._showload) {
clearTimeout(opt._showload);
if (opt._showloaded)
uni.hideToast();
}
if (opt.pagethis && opt.pagethis._stopPullDown) {
opt.pagethis._stopPullDown = false;
uni.stopPullDownRefresh();
}
},
success: res => {
var json = app.json_parse(res.data);
if (json === null) {
res._url = url;
res._post = opt.data;
app.uperr("h5.noajaxjson", res);
return reject({
errmsg: '返回JSON错误:' + res.statusCode
});
}
var dictversion = res.header[app.globalData.tokenfield + 're'];
if (dictversion) {
console.log('restorage new', dictversion);
app.globalData._restorage = true; //通知app.vue自动刷新
}
var newauth = '';
for (var i in res.header) {
if (i.toLowerCase() == '_ciyauth')
newauth = res.header[i];
}
if (!newauth)
newauth = json['_ciyauth'];
if (newauth) {
console.log('newauth new', newauth);
app.setstorage('_' + app.globalData.tokenfield, newauth);
}
if (json.code != 1) {
if (json.code == 2) {
app.removestorage('me');
var pg = app.getpage();
if (!pg.isPage)
return reject({
errmsg: ''
});
pg.getauth().then(res => {
if (res.me.id > 0)
makeRequest();
else
uni.navigateBack();
});
return;
} else {
return reject(json);
}
}
try {
//delete json.code;
if (opt.cache > 0) {
app.setstorage(opt.cachekey, {
d: json,
t: new Date().getTime()
});
}
return resolve(json);
} catch (e) {
res._url = url;
res._post = opt.data;
res._cache = e;
app.uperr("h5.ajaxrun", res);
return reject({
errmsg: '请求错误:' + e.message
});
}
}
});
}
makeRequest();
}).catch(e => {
if (e.error != 'NULL') {
//app.toast(e.errmsg);
}
return e;
});
};
app.methods.setuserstorage = function(json) {
var app = this;
app.setstorage("me", json.me);
var pnttrack = app.getstorage('_pnttrack', {});
if (!(pnttrack instanceof Object))
pnttrack = {};
var day = new Date();
day.setHours(0, 0, 0, 0);
day = parseInt(day.getTime() / 1000);
for (var pt in json.pnttrack) {
let track = json.pnttrack[pt];
let cnt = 0;
if (pnttrack[track.id])
cnt = pnttrack[track.id].pnt;
pnttrack[track.id] = {
name: track.name,
p: track.point,
h24: track.limh24,
day: day,
cnt: cnt
}
}
app.setstorage("_pnttrack", pnttrack);
var sav = app.getstorage('g', {});
var arr = json.storage;
for (var code in arr) {
if (code == 'cata') {
for (var c in arr[code]) {
if (arr[code][c].cbid > 0)
continue;
var types = arr[code][c].codeid;
var codes = new Array();
for (var d in arr[code]) {
if (arr[code][d].cbid != arr[code][c].id)
continue;
var cs = {};
cs.id = arr[code][d].codeid;
cs.name = arr[code][d].name;
if (arr[code][d].extdata)
cs.extdata = arr[code][d].extdata;
if (arr[code][d].clas)
cs.clas = arr[code][d].clas;
if (arr[code][d].isuse != 1)
cs.isuse = arr[code][d].isuse;
if (arr[code][d].upid > 0) {
for (var i in arr[code]) {
if (arr[code][d].upid == arr[code][i].id) {
cs.upid = arr[code][i].codeid;
break;
}
}
}
codes.push(cs);
}
if (types)
sav[types] = codes;
}
} else {
sav[code] = arr[code];
}
}
app.setstorage('g', sav);
return {
me: json.me
}
};
app.methods.appupdate = async function(plat, cb) {
var app = this;
// #ifdef APP-PLUS
plus.runtime.getProperty(plus.runtime.appid, async widgetInfo => {
app.callfunc({
func: 'login.getappver',
showload: false,
data: {
vercode: widgetInfo.versionCode
},
success: async json => {
if (!json.url)
return app.toast('已经是最新版本');
if (json.must && typeof(cb) == 'function') {
if (!await cb(json.verinfo))
return;
}
app.toast('更新中...');
uni.downloadFile({
url: json.url,
success: res => {
if (res.statusCode !== 200)
return app.alert('更新文件下载失败' + json.url);
plus.runtime.install(res.tempFilePath, {
force: true
}, function() {
app.toast('更新成功,即将热重启', () => {
plus.runtime.restart();
});
}, function(e) {
console.log(e);
app.alert('更新失败:' + e.message);
});
}
});
}
});
});
// #endif
// #ifdef MP-WEIXIN
if (plat != 'app') {
const updateManager = uni.getUpdateManager();
updateManager.onCheckForUpdate(res => {
console.log('onCheckForUpdate', res);
if (!res.hasUpdate)
return app.toast('已经是最新版本');
app.toast('新版本更新中...');
updateManager.onUpdateReady(async res => {
console.log('onUpdateReady', res);
if (typeof(cb) == 'function') {
if (await cb('新版本已经准备好,是否重启应用?'))
updateManager.applyUpdate();
}
});
updateManager.onUpdateFailed(res => {
console.log('onUpdateFailed', res);
app.alert('更新失败,请重新启动微信再试');
});
});
}
// #endif
};
app.methods.connectbt = function(devup, devtype, deviceid) {
var app = this;
if (app.globalData.dev_bt[devup]) {
app.globalData.dev_bt[devup].bt_devclose();
} else {
app.globalData.dev_bt[devup] = new cbt.CBTBase(devup, devtype);
}
var btdev = app.globalData.dev_bt[devup];
btdev.oncreated = services => {
btdev.setwrt(services);
}
// btdev.onfail = res => {
// }
// btdev.onsuccess = res => {
// }
btdev.bt_devopen(deviceid);
};
app.methods.getstorage = function(key, def) {
def = def || '';
var x = uni.getStorageSync(key);
if (x == '')
return def;
var json = this.json_parse(x);
if (json !== null)
return json;
return x;
};
app.methods.setstorage = function(key, val) {
if (val === undefined)
return this.removestorage(key);
var x = val;
if (typeof(val) == 'object')
x = JSON.stringify(val);
return uni.setStorageSync(key, x);
};
app.methods.clearstorage = function() {
return uni.clearStorageSync();
};
app.methods.removestorage = function(key) {
var keylen = key.length - 1;
if (key.substring(keylen) != '*')
return uni.removeStorageSync(key);
key = key.substring(0, keylen);
var keys = uni.getStorageInfoSync();
for (var i in keys.keys) {
if (keys.keys[i].substring(0, keylen) == key)
uni.removeStorageSync(keys.keys[i]);
}
};
ap.mixin({
data() {
return {
header_statusbar_height: 0, //顶部状态栏(时间电池、躲过刘海/镂空位置)
header_title_height: 40, //顶部标题栏高度(正好容纳胶囊)
header_title_margin: 0, //顶部标题栏左右留白(正好躲过胶囊,且可使文字居中)
footer_safe_height: 0, //底部安全高度(躲过刘海屏、底部横线等)
pageclass: 'dark',
editdata: {},
pagedata: {}, //外部g.page_init
isPage: false,
jsnurl: {},
pageno: 0,
init: {},
srv: 't',
meta: {
theme: 'light',
bgcolor: '#ffffff',
styles: {
'min-height': '100vh',
'background-color': '#ffffff',
'color': '#000000'
},
style: 'min-height:100vh;background-color:#ffffff;color:#000000;',
fontsize: '16px',
pulldown: true,
},
opn: {}, //页面传参
me: {},
//g: {}, //本地与dydict整合onshow更新本地同时合并dydict。
};
},
created() {}, //全局混入的 created 钩子被调用
mounted() {},
onLoad(opn) {
this.isPage = true;
if (opn.scene) {
var scene = decodeURIComponent(opn.scene);
console.log(scene);
var obj = this.getstrparam(scene);
for (var i in obj)
opn[i] = obj[i];
}
this.opn = opn;
var upid = this.toint(this.opn.upid);
if (upid > 0)
this.setstorage('upid', upid);
this.pagepost = { //page快捷检索post值
query: {}
};
this.header_statusbar_height = app.globalData._header_statusbar_height;
this.header_title_height = app.globalData._header_title_height;
this.header_title_margin = app.globalData._header_title_margin;
this.footer_safe_height = app.globalData._footer_safe_height;
this.pagedata = app.globalData.ciy_page_data;
this.jsnurl = app.globalData.jsnurl;
//this.constant = {maxtimes: 9999999999999};
this.me = this.getme();
// if (app.globalData.ciy_page_g)
// this.g = app.globalData.ciy_page_g;
// else
// this.g = this.getstorage('g', {});
uni.hideTabBar({
fail: res => {}
});
},
computed: {
g() {
if (app.globalData.ciy_page_g)
return app.globalData.ciy_page_g;
else
return this.getstorage('g', {});
}
},
onShow() {
this.settheme();
this.setfont();
this.me = this.getme();
// var ref = this.getrefsSync('tabbar');
// if (ref)
// ref.loadtabbardata();
},
onPageScroll(e) {
var app = getApp();
if (Object.keys(app.globalData.scrollcbs).length == 0)
return;
for (var i in app.globalData.scrollcbs) {
app.globalData.scrollcbs[i](e);
}
},
methods: {
showe(e) {
console.log('showe', e);
return '';
},
callfunc(opt) {
opt.pagethis = this;
return getApp().callfunc(opt);
},
calltxt(opt) {
return new Promise((resolve, reject) => {
opt = opt || {};
uni.request({
url: opt.url,
data: opt.data,
dataType: 'text',
method: opt.data ? 'POST' : 'GET',
header: opt.header,
fail: res => {
var errmsg = res.errMsg || 'nofind errMsg.';
if (errmsg.indexOf('fail abort') > 0)
errmsg = '网络信号不好';
else if (errmsg.indexOf('equest:fail timeout') > 0)
errmsg = '网络访问超时';
else if (errmsg.indexOf('equest:fail') > 0)
errmsg = '网络不可用';
return reject({
errmsg: errmsg
});
},
success: res => {
if (res.statusCode == 200)
return resolve(res.data);
return reject({
errmsg: res.data
});
}
});
});
},
getme() {
return getApp().getme();
},
uperr(type, msg) {
return getApp().uperr(type, msg);
},
json_parse(data) {
return getApp().json_parse(data);
},
json_string(data) {
try {
return JSON.stringify(data);
} catch (e) {
console.log('json_string', e);
}
return '';
},
getstorage(key, def) {
var app = getApp();
return app.getstorage(key, def);
},
setstorage(key, val) {
var app = getApp();
return app.setstorage(key, val);
},
clearstorage() {
return uni.clearStorageSync();
},
removestorage(key) {
var app = getApp();
return app.removestorage(key);
},
lang(str) {
if (typeof(this.$t) == 'function')
return this.$t(str);
return str;
},
async gourl(b, type, initdata, initkey) { //url支持 http[web]、![原型]、*[alert提示]、$[需登录常规url]、常规url
var url = '';
if (typeof(b) != 'string') {
url = b.currentTarget.dataset.url;
if (!initdata) {
initdata = b.currentTarget.dataset.data;
}
if (!initkey) {
initkey = b.currentTarget.dataset.key;
}
} else {
url = b;
}
if (!initdata)
initdata = {};
if (!initkey)
initkey = 'base';
if (!url)
return console.warn('gourl传参错误:' + url);
var app = getApp();
if (url.substring(0, 4) == 'http') {
this.goweb(url, name);
} else if (url.substring(0, 1) == '!') {
var dmos = url.substring(1).split('|');
if (dmos.length < 2)
dmos[1] = '';
uni.navigateTo({
url: '/pages/pub/web?web=' + encodeURIComponent(app.globalData.demourl + '?menuid=' + dmos[0] + '&title=no&tag=' + dmos[1]) + (dmos[2] ? '&name=' + dmos[2] : ''),
animationType: 'pop-in',
animationDuration: 1000
});
} else if (url.substring(0, 1) == '*') {
this.alert(url.substring(1));
} else {
if (url.substring(0, 1) == '$') {
url = url.substring(1);
var auth = await this.getauth();
if (auth.me.id == 0)
return;
}
if (url.substring(0, 1) == '%') {
url = url.substring(1);
var auth = await this.getauth('info');
if (auth.me.id == 0)
return;
}
if (url.substring(0, 1) == '^') {
url = url.substring(1);
var auth = await this.getauth('real');
if (auth.me.id == 0)
return;
}
if (url.substring(0, 1) == '&') {
url = url.substring(1);
var auth = await this.getauth('bank');
if (auth.me.id == 0)
return;
}
if (url.substring(0, 1) == '*') {
url = url.substring(1);
var auth = await this.getauth('cciy');
if (auth.me.id == 0)
return;
}
app.globalData.ciy_page_data[initkey] = {
...initdata
};
if (this.isPage)
app.globalData.ciy_page_g = this.g;
if (type == 'redirect') {
uni.redirectTo({
url: url,
animationType: 'pop-in',
animationDuration: 1000,
fail: res => {
uni.switchTab({
url: url,
fail: res => {
return this.toast(name + ' 未定义链接:' + url);
}
});
}
});
} else {
uni.navigateTo({
url: url,
animationType: 'pop-in',
animationDuration: 1000,
fail: res => {
uni.switchTab({
url: url,
fail: res => {
return this.toast(name + ' 未定义链接:' + url);
}
});
}
});
}
}
},
goweb(url, name) {
var app = getApp();
url += (url.indexOf('?') == -1) ? '?' : '&';
url += '_ciyauth=' + app.getstorage('_' + app.globalData.tokenfield);
uni.navigateTo({
url: '/pages/pub/web?web=' + encodeURIComponent(url) + (name ? '&name=' + name : ''),
animationType: 'pop-in',
animationDuration: 1000
});
},
goloc(lat, lng, bet) {
bet = bet || 10000000;
uni.openLocation({
latitude: this.tofloat(lat) / bet,
longitude: this.tofloat(lng) / bet
});
},
gophone(phone) {
if (!phone)
return;
uni.makePhoneCall({
phoneNumber: phone
});
},
async goani(opn, cb, othcb) {
return new Promise(async (resolve, reject) => {
var aniinit = {
timingFunction: 'ease',
transformOrigin: '50% 50% 0',
delay: 0
};
if (typeof(opn) == 'string')
opn = {
anis: opn
};
opn.init = opn.init || aniinit;
if (typeof(opn.anis) == 'string') {
var anist = opn.anis.split('|');
var aniarr = [];
for (var i in anist) {
if (anist[i] == 'hide') {
aniarr.push({
hide: true
});
continue;
}
var stp = anist[i].split(',');
var dur = 0;
for (var s in stp) {
var pre = stp[s].substring(0, 2);
var val = stp[s].substring(2);
if (pre == 'ra')
aniarr.push({
rotate: parseFloat(val)
});
else if (pre == 'rx')
aniarr.push({
rotateX: parseFloat(val)
});
else if (pre == 'ry')
aniarr.push({
rotateY: parseFloat(val)
});
else if (pre == 'rz')
aniarr.push({
rotateZ: parseFloat(val)
});
else if (pre == 'sa')
aniarr.push({
scale: parseFloat(val)
});
else if (pre == 'sx')
aniarr.push({
scaleX: parseFloat(val)
});
else if (pre == 'sy')
aniarr.push({
scaleY: parseFloat(val)
});
else if (pre == 'sz')
aniarr.push({
scaleZ: parseFloat(val)
});
else if (pre == 'ta')
aniarr.push({
translate: val
});
else if (pre == 'tx')
aniarr.push({
translateX: val
});
else if (pre == 'ty')
aniarr.push({
translateY: val
});
else if (pre == 'tz')
aniarr.push({
translateZ: val
});
else if (pre == 'wa')
aniarr.push({
skew: parseFloat(val)
});
else if (pre == 'wx')
aniarr.push({
skewX: parseFloat(val)
});
else if (pre == 'wy')
aniarr.push({
skewY: parseFloat(val)
});
else if (pre == 'op')
aniarr.push({
opacity: parseFloat(val)
});
else if (pre == 'bc')
aniarr.push({
backgroundColor: val
});
else if (pre == 'ww')
aniarr.push({
width: val
});
else if (pre == 'hh')
aniarr.push({
height: val
});
else if (pre == 'tt')
aniarr.push({
top: val
});
else if (pre == 'll')
aniarr.push({
left: val
});
else if (pre == 'bb')
aniarr.push({
bottom: val
});
else if (pre == 'rr')
aniarr.push({
right: val
});
else
dur = this.toint(stp[s]);
}
aniarr.push({
step: {
duration: dur
}
});
}
opn.anis = aniarr;
}
var animation = uni.createAnimation(opn.init);
for (var aa in opn.anis) {
var key = Object.keys(opn.anis[aa])[0];
var val = opn.anis[aa][key];
if (key == 'step') {
val.duration = this.toint(val.duration);
if (val.duration < 16)
val.duration = 100;
animation.step(val);
cb(animation.export());
await this.sleep(val.duration);
animation = uni.createAnimation(opn.init);
} else if (key == 'hide') {
if (typeof(othcb) == 'function')
othcb(key, val);
} else if (animation[key]) {
if (typeof(val) == 'object')
animation[key](...val);
else
animation[key](val);
}
}
resolve();
}).catch(e => {
return e;
});
},
copyboard(b, bsilent) {
if (this.isobject(b))
b = b.currentTarget.dataset.text;
if (!b)
return;
uni.setClipboardData({
data: b
});
if (!bsilent)
app.toast('已复制到剪贴板');
},
isfloat0(num) {
num = parseFloat(num);
if (isNaN(num))
return true;
return (num < 0.001 && num > -0.001);
},
isarray(value) {
return Object.prototype.toString.call(value).toLowerCase().indexOf('object array') > -1;
},
isobject(value) {
return Object.prototype.toString.call(value).toLowerCase().indexOf('object object') > -1;
},
islocalmedia(file) {
if (!file)
return false;
if (file.substring(0, 9) == 'wxfile://')
return true;
return false;
},
isimg(file) {
var ext = this.file_ext(file);
return (["PNG", "JPG", "GIF", "BMP", "WEBP", "SVG"].indexOf(ext) >= 0);
},
isvideo(file) {
var ext = this.file_ext(file);
return (["MP3", "MP4"].indexOf(ext) >= 0);
},
file_ext(file) {
if (typeof(file) != 'string') {
if (file.name)
file = file.name;
if (file.tempFilePath)
file = file.tempFilePath;
}
var d = file.lastIndexOf('.');
if (d >= 0) {
var ext = file.substring(d + 1).toUpperCase();
if (ext == 'JPEG' || ext == 'JPE')
return 'JPG';
return ext;
}
return '';
},
file_stor(url, pre) {
if (!url)
return '';
if (this.islocalmedia(url))
return url;
if (url.substring(0, 4).toLowerCase() == 'http')
return url;
var app = getApp();
var cdnurl = app.globalData.storlist[url.substring(0, 1)];
if (this.isobject(cdnurl)) {
var fast = false;
if (url.indexOf('banner') > -1)
fast = true;
if (pre)
fast = true;
if (fast)
cdnurl = cdnurl.fast;
else
cdnurl = cdnurl.all;
}
return cdnurl + url.substring(1) + (pre ? pre : '');
},
hasstr(str, find) {
if (!str)
return false;
return str.indexOf(find) > -1;
},
ccode(arr, value, field, nonestr) {
field = field || 'name';
nonestr = nonestr || '--';
if (typeof(arr) != 'object') {
arr = this.g[arr] || this.init[arr];
if (typeof(arr) != 'object')
return '!';
}
for (var i = 0; i < arr.length; i++) {
if (arr[i].id == value) {
if (field == 'idx')
return i;
if (field == '_obj')
return arr[i];
if (arr[i][field])
return arr[i][field];
return nonestr;
}
}
if (field == '_obj')
return null;
if (value < 1)
return nonestr;
return ''; //[' + value + ']';
},
scode(arr, ids, field) {
if (typeof(arr) != 'object')
return ['!'];
ids = ids || '';
var vals = ids.split(',');
var names = [];
for (var v = 0; v < vals.length; v++) {
for (var i = 0; i < arr.length; i++) {
if (arr[i].id != vals[v])
continue;
if (field)
names.push(arr[i][field]);
else
names.push(arr[i]);
}
}
return names;
},
mcode(arr, value, field) {
if (typeof(arr) != 'object')
return [];
var ret = [];
for (var x = 0; x < 100; x++) {
var bfind = false;
for (var i = 0; i < arr.length; i++) {
if (arr[i].id == value) {
bfind = true;
value = arr[i].upid;
if (field)
ret.unshift(arr[i][field]);
else
ret.unshift(arr[i]);
break;
}
}
if (!bfind)
break;
}
return ret;
},
bcode(arr, value, field) {
if (typeof(arr) != 'object')
return ['!'];
var names = [];
for (var i = 0; i < arr.length; i++) {
if ((value & (1 << i))) {
if (field)
names.push(arr[i][field]);
else
names.push(arr[i]);
}
}
return names;
},
enbase64(str) {
var c1, c2, c3;
var base64EncodeChars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var i = 0,
len = str.length,
string = '';
while (i < len) {
c1 = str.charCodeAt(i++) & 255;
if (i == len) {
string += base64EncodeChars.charAt(c1 >> 2);
string += base64EncodeChars.charAt((c1 & 3) << 4);
string += "==";
break;
}
c2 = str.charCodeAt(i++);
if (i == len) {
string += base64EncodeChars.charAt(c1 >> 2);
string += base64EncodeChars.charAt(((c1 & 3) << 4) | ((c2 & 240) >> 4));
string += base64EncodeChars.charAt((c2 & 15) << 2);
string += "=";
break;
}
c3 = str.charCodeAt(i++);
string += base64EncodeChars.charAt(c1 >> 2);
string += base64EncodeChars.charAt(((c1 & 3) << 4) | ((c2 & 240) >> 4));
string += base64EncodeChars.charAt(((c2 & 15) << 2) | ((c3 & 192) >> 6));
string += base64EncodeChars.charAt(c3 & 63)
}
return string;
},
svg2bg(svg) {
if (!svg)
return '';
if (svg.substring(0, 4) == 'url(')
return svg;
return "url('data:image/svg+xml;charset=utf-8;base64," + this.enbase64(svg) + "')";
},
topad0(num, length) {
if ((num + "").length > length)
return num;
return (Array(length).join('0') + num).slice(-length);
},
tonumtho(num) {
return this.toint(num).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
},
tonumdec(num, showzero, len) {
len = len || 2; // 与tofix不同点小数长度不变如 1.10
var m2 = Math.round((num - parseInt(num)) * Math.pow(10, len));
if (m2 == 0) {
if (showzero)
return '.' + '0'.repeat(len);
else
return '';
}
m2 = m2 + '';
if (m2.length < len)
m2 = '0'.repeat(len - m2.length) + m2;
return '.' + m2;
},
tocciy(cciy) {
if (!cciy || cciy == '0') //cciy必须为字符串否则js无法处理
return '';
return 'cx' + cciy.substring(0, 1) + '...' + cciy.substring(cciy.length - 6);
},
tostr(obj) {
if (!obj)
return '';
if (typeof(obj) == 'object')
return JSON.stringify(obj).replace(/"/g, '“');
return obj + '';
},
toint(val, defval) {
defval = defval || 0;
var ret = parseInt(val);
if (isNaN(ret))
return defval;
else if (ret == undefined)
return defval;
else
return ret;
},
tofloat(val, defval) {
defval = defval || 0;
var ret = parseFloat(val);
if (isNaN(ret))
return defval;
else
return ret;
},
tostamp(dt) {
if (dt === undefined)
dt = new Date();
var t = dt.getTime();
if (isNaN(t))
return 0;
return parseInt(t / 1000);
},
todatetime(time, format, nostr) {
nostr = nostr || '--';
if (time == 0)
return nostr;
var t;
if (time instanceof Date) {
if (time.getTime() == 0)
return nostr;
t = time;
} else if (time == -1)
t = new Date();
else
t = new Date(time * 1000);
var year = t.getFullYear();
var month = t.getMonth() + 1;
var month0 = month < 10 ? '0' + month : month;
var day = t.getDate();
var day0 = day < 10 ? '0' + day : day;
var hour = t.getHours();
var hour0 = hour < 10 ? '0' + hour : hour;
var minute = t.getMinutes();
var minute0 = minute < 10 ? '0' + minute : minute;
var second = t.getSeconds();
var second0 = second < 10 ? '0' + second : second;
if (format == 'id')
return day0 + hour0 + minute;
if (format == 'H')
return year + "-" + month0 + "-" + day0 + " " + hour0;
if (format == 'd')
return year + "-" + month0 + "-" + day0;
if (format == 'D')
return year + "年" + month + "月" + day + '日';
if (format == 'x')
return month0 + "-" + day0;
if (format == 'm')
return year + "-" + month0;
if (format == 'n')
return year + "-" + month;
if (format == 'y')
return year;
if (format == 'M')
return year + "年" + month + '月';
if (format == 'i')
return hour0 + ":" + minute0;
if (format == 's')
return year + "-" + month0 + "-" + day0 + " " + hour0 + ":" + minute0 + ":" +
second0;
if (format == 'st')
return month0 + "-" + day0 + " " + hour0 + ":" + minute0;
return year + "-" + month0 + "-" + day0 + " " + hour0 + ":" + minute0;
},
tofix(num, length) {
//length正数小数点保留n位不去0。
//负数小数点保留n位全0则不显示。
//0按数长保留尽量少的位数显示。
//不填,-4
num = parseFloat(num);
if (isNaN(num))
num = 0;
if (length === undefined)
length = -4;
if (length == 0) {
if (num >= 1000)
return parseInt(num);
var numlen = (parseInt(num) + '').length;
length = 4 - numlen;
if (Math.abs(num % 1) < Math.pow(0.1, length))
return parseInt(num);
num = num.toFixed(length);
var y = '.';
for (var i = 0; i < length; i++)
y += "0";
if (num.substring(num.length - length - 1) == y)
num = num.substring(0, num.length - length - 1);
return num;
} else if (length < 0) {
num = num.toFixed(-length); //xx.xx
var inde = num.split('.');
if (inde[1] && /^0+$/.test(inde[1]))
return inde[0];
return num.replace(/\.?0+$/, '');
}
num = num.toFixed(length);
return num;
},
tounit(ori) {
var us = ori.split('|');
if (us.length == 5)
return '1' + us[4] + us[3] + us[2] + ' 1' + us[2] + us[1] + us[0];
else if (us.length == 3)
return '1' + us[2] + us[1] + us[0];
return us[0];
},
tocyc(ori) {
if (ori == 0)
return '--';
if (ori < 0)
return -ori + this.lang('月');
if (ori >= 86400)
return parseInt(ori / 86400) + this.lang('天');
return parseInt(ori / 60) + this.lang('分钟');
},
tomsk(ori, pstr) {
if (!ori)
return '';
var retstr = '';
ori = ori + '';
if (ori.length > pstr.length) {
retstr = ori.substring(0, ori.length - pstr.length);
ori = ori.substring(ori.length - pstr.length);
}
for (var i = 0; i < Math.min(ori.length, pstr.length); i++) {
if (pstr.charAt(i) == '*')
retstr += '*';
else
retstr += ori.charAt(i);
}
return retstr;
},
totimespan(time, bestr, zero, before) {
bestr = bestr || '';
zero = zero || this.lang('time.now');
if (time == 0 || time === undefined)
return '--';
var t = new Date(time * 1000);
var diff = (new Date() - t) / 1000;
if (before)
diff = -diff;
if (diff < 10) //10秒以内
return zero;
return this.totimesec(diff, bestr);
},
totimesec(diff, bestr) {
bestr = bestr || '';
if (diff < 60) //60秒以内
return parseInt(diff) + this.lang("秒") + bestr;
if (diff < 3600) //60分以内
return parseInt(diff / 60) + this.lang("分钟") + bestr;
if (diff < 86400) //24小时以内
return parseInt(diff / 3600) + this.lang("小时") + bestr;
if (diff < 2592000) //30天以内
return parseInt(diff / 86400) + this.lang("天") + bestr;
if (diff < 31536000) //12月以内
return parseInt(diff / 2592000) + this.lang("个月") + bestr;
return parseInt(diff / 31536000) + this.lang("年") + bestr;
},
totimepoint(time, bsecond) {
if (time <= 0 || time > 86400)
return '';
time--;
var hour = this.toint(time / 3600);
var minute = this.toint((time - hour * 3600) / 60);
var ret = this.topad0(hour, 2) + ':' + this.topad0(minute, 2);
if (!bsecond)
return ret;
var second = time - hour * 3600 - minute * 60;
ret += ':' + this.topad0(second, 2);
return ret;
},
todayage(time, noday) {
if (time == 0 || time === undefined)
return '--';
var t = new Date(time * 1000);
var diff = (new Date() - t) / 1000;
diff = parseInt(diff / 86400) + 1;
if (diff < 30) //30天以内
return diff + "天";
var month = parseInt(diff / 30);
if (noday)
return month + '个月';
return month + '个月 ' + (diff - month * 30) + '天';
},
tobr(txt, autohtml) {
if (!txt)
return '';
if (!autohtml) {
txt = txt.replace(/</g, '&lt;');
txt = txt.replace(/>/g, '&gt;');
//txt = txt.replace(/\|/g, '<br/>');
}
txt = txt.replace(/\n/g, '<br/>');
return txt;
},
pagenoscroll(b) {
// #ifdef MP-WEIXIN
if (b) {
wx.setPageStyle({
style: {
overflow: 'hidden'
}
});
} else {
wx.setPageStyle({
style: {
overflow: 'auto'
}
});
//uni.setPageMeta()
}
// #endif
// #ifdef H5
if (b) {
document.body.style.overflow = 'hidden';
} else {
document.body.style.overflow = 'auto';
}
// #endif
},
settheme(theme) {
if (theme) {
this.setstorage('_theme', theme);
} else {
theme = this.getstorage('_theme');
if (!theme) {
if (app.globalData._sysinfo.theme == 'dark')
theme = 'dark';
}
}
var bgcolor = '#f7f8f8';
var txtcolor = '#576067'; //txt5
if (theme == 'dark') {
bgcolor = '#151a1b';
txtcolor = '#c2cad0';
} else {
theme = 'light';
}
this.meta.theme = theme;
this.meta.bgcolor = bgcolor;
this.meta.styles['background-color'] = bgcolor;
this.meta.styles['color'] = txtcolor;
this.meta.style = Object.keys(this.meta.styles).map(key => key + ':' + this.meta.styles[
key]).join(';') + ';';
this.pageclass = theme;
// // #ifdef MP-WEIXIN
// wx.setBackgroundTextStyle({
// textStyle: theme
// })
// // #endif
},
setfont(font) {
// 空lg xl xxl xxl
var app = getApp();
if (!font) {
font = this.getstorage('_font');
if (!font) {
font = 'def';
var fsize = app.globalData._sysinfo.fontSizeSetting * app.globalData._sysinfo.fontSizeScaleFactor;
if (fsize >= 20 && fsize < 30)
font = 'lg';
if (fsize >= 30 && fsize < 40)
font = 'xl';
else if (fsize >= 40)
font = 'xxl';
//标准:16*1=16 1:18*1.1=19.8 2:18*1.12=20.16 3:18*1.125=20.25 4:22*1.4=30.8 5:25*1.55=38.75 max:26*1.65=42.9
}
} else {
this.setstorage('_font', font);
}
var fontsize;
if (font == 'def')
fontsize = 30;
else if (font == 'lg')
fontsize = 40;
else if (font == 'xl')
fontsize = 50;
else if (font == 'xxl')
fontsize = 60;
else
fontsize = this.toint(font);
if (fontsize < 20)
fontsize = 30;
var fz = (fontsize / 750 * app.globalData._sysinfo.windowWidth) + 'px';
this.meta.styles['font-size'] = fz;
this.meta.style = Object.keys(this.meta.styles).map(key => key + ':' + this.meta.styles[key]).join(';') + ';';
this.meta.fontsize = fz;
},
executepnt(pntid, post) {
var me = this.getme();
if (me.id == 0)
return;
var pnttrack = this.getstorage('_pnttrack', {});
if (!this.isobject(pnttrack[pntid]))
return;
var day = this.str2date(this.todatetime(-1, 'd')).getTime() / 1000;
var cnt = 0;
if (day == pnttrack[pntid].day) {
cnt = this.toint(pnttrack[pntid].cnt);
if (pnttrack[pntid].h24 > 0 && pnttrack[pntid].h24 <= cnt)
return;
}
cnt += this.toint(pnttrack[pntid].p);
pnttrack[pntid].day = day;
pnttrack[pntid].cnt = cnt;
if (!post)
post = {};
post.id = pntid;
this.setstorage('_pnttrack', pnttrack);
this.callfunc({
func: 'main.pnt_up',
loadhide: true,
data: post
}).then(res => {
if (res.code != 1)
return;
if (res.msg)
this.toast(res.msg);
});
},
setTabbar(nameobj) {
var app = this;
if (nameobj instanceof Array) {
app.globalData.tabbarArr = nameobj;
return;
}
if (nameobj instanceof Object) {
for (var i in app.globalData.tabbarArr) {
if (!nameobj[app.globalData.tabbarArr[i].name])
continue;
var obj = nameobj[app.globalData.tabbarArr[i].name];
for (var o in obj) {
app.globalData.tabbarArr[i][o] = obj[o];
}
}
}
app.getpage().getrefs('tabbar').then(ref => {
ref.loadtabbardata();
});
},
async getauth(type) {
return new Promise((resolve, reject) => {
this.$nextTick(() => {
this.getrefs('auth').then(ref => {
ref.Open(auth => {
if (auth.me.id == 0)
return resolve(auth);
this.me = auth.me;
//this.g = this.objdeepmerge(this.g, this.getstorage('g', {}));
if (type == 'info' && !this.me.name) {
this.askmsg('请先填写个人信息').then(res => {
if (res == 'cancel')
return;
uni.redirectTo({
url: '/pages/me/user_info'
});
});
return;
}
if (type == 'real' && !this.me.truename) {
this.askmsg('请进行实名认证').then(res => {
if (res == 'cancel')
return;
uni.redirectTo({
url: '/pages/me/safe_real'
});
});
return;
}
if (type == 'bank' && !this.me.bankname) {
this.alert('请填写银行信息').then(res => {
if (res == 'cancel')
return;
uni.redirectTo({
url: '/pages/me/user_bank'
});
});
return;
}
if (type == 'cciy' && this.me.cciy.length < 10) {
this.alert('请先申请众识码').then(res => {
if (res == 'cancel')
return;
uni.redirectTo({
url: '/pages/me/safe_ccub'
});
});
return;
}
resolve(auth);
}, type == 'relogin');
});
});
}).catch(e => {
console.error('getauth error', e);
return e;
});
},
async scanqr() {
return new Promise((resolve, reject) => {
var ret = {};
if (process.env.NODE_ENV === 'development') {
this.inputmsg('输入二维码').then(itm => {
if (!itm.text)
return;
ret.type = 'input';
ret.code = itm.text;
resolve(ret);
});
return;
}
var res = uni.scanCode().then(res => {
ret.type = res.scanType;
ret.code = res.result;
if (!ret.code)
ret.code = res.code;
resolve(ret);
}).catch(res => {
console.log('scanCode err', res);
resolve({
type: 'error'
});
});
}).catch(e => {
return e;
});
},
async popmenu(opn) { //items one rowcount title
return new Promise((resolve, reject) => {
this.getrefs('popmenu').then(ref => {
ref.Open(opn).then(item => {
if (typeof(opn.closecb) == 'function')
opn.closecb();
if (item.url) {
if (item.data)
this.gourl(item.url, item.type, {
...item.data
}, item.key);
else
this.gourl(item.url, item.type);
return;
}
if (item.func && typeof(this[item.func]) == 'function') {
this[item.func](item);
return;
}
resolve(item);
});
});
}).catch(e => {
return e;
});
},
async toast(opn) {
var ref = await this.getrefs('toast');
if (!ref)
return this.alert('no find toast');
return await ref.Open(opn);
},
async alert(opn, btns) {
if (!opn)
return;
if (typeof(opn) == 'string') {
opn = {
content: opn
};
}
if (btns) {
opn.btns = btns;
}
var ref = await this.getrefs('alert');
if (!ref)
return this.alert('no find alert');
return await ref.Open(opn);
},
async askmsg(content, btns) {
var opn = {
content
};
if (!btns)
btns = [{
name: '确定',
btn: 'ok'
}, {
name: '取消',
btn: 'cancel',
cls: 'def'
}];
else if (typeof(btns) == 'string')
btns = [{
name: btns,
btn: 'ok'
}, {
name: '取消',
btn: 'cancel',
cls: 'def'
}];
opn.btns = btns;
var ref = await this.getrefs('alert');
if (!ref)
return this.alert('no find alert');
return await ref.Open(opn);
},
async inputmsg(opn, btns) {
if (typeof(opn) == 'string')
opn = {
content: opn
};
opn = opn || {};
if (opn.title === undefined)
opn.title = '操作项';
opn.ele = opn.ele || 'input';
if (!btns)
opn.btns = [{
name: '确定',
btn: 'ok'
}, {
name: '取消',
btn: 'cancel',
cls: 'def'
}];
else if (typeof(btns) == 'string')
opn.btns = [{
name: btns,
btn: 'ok'
}, {
name: '取消',
btn: 'cancel',
cls: 'def'
}];
else
opn.btns = btns;
var ref = await this.getrefs('alert');
if (!ref)
return this.alert('no find alert');
var ret = await ref.Open(opn);
if (typeof(ret) == 'string')
return {
btn: 'cancel'
};
return ret;
},
async sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
},
async load_ciydict(url) {
if (url.indexOf('.local.') === -1)
url = url.replace('http://', 'https://');
return new Promise((resolve, reject) => {
uni.request({
url: url,
dataType: 'text',
method: 'GET',
fail: res => {
res._url = url;
this.uperr("h5.loadjs.fail", res);
return reject({
errmsg: 'dict' + res.errMsg
});
},
success: res => {
var ind = res.data.indexOf('[');
if (ind == -1)
return reject({
errmsg: 'dict数据缺少数组'
});
if (res.data.substring(0, 8) != 'var ciy_')
return reject({
errmsg: 'dict数据格式错误'
});
var name = res.data.substring(8, ind - 1);
var json = this.json_parse(res.data.substring(ind));
if (json === null) {
this.uperr("app.loadjs.json", res);
return reject({
errmsg: 'dict数组解析错误'
});
}
return resolve({
code: 1,
name: name,
arr: json
});
}
});
}).catch(e => {
return e; //不返回res为 undefined
});
},
async load_svgicon(url) {
if (url.indexOf('.local.') === -1)
url = url.replace('http://', 'https://');
return new Promise((resolve, reject) => {
uni.request({
url: url,
dataType: 'text',
method: 'GET',
fail: res => {
res._url = url;
this.uperr("h5.loadsvgicon.fail", res);
return reject({
errmsg: 'dict' + res.errMsg
});
},
success: res => {
var ind = res.data.indexOf(':');
if (ind == -1)
return reject({
errmsg: 'svgicon数据缺少合规图标'
});
var lines = res.data.split('\n');
var svgs = {};
for (var i in lines) {
var idx = lines[i].indexOf(':');
if (idx == -1)
continue;
svgs[lines[i].substring(0, idx)] = lines[i].substring(idx + 1);
}
return resolve(svgs);
}
});
}).catch(e => {
return e; //不返回res为 undefined
});
},
shareparam(opn) {
var app = getApp();
var param = {};
param.title = opn.title;
if (opn.img)
param.imageUrl = opn.img;
if (opn.promise)
param.promise = opn.promise;
var urlp = '';
for (var u in opn.query) {
urlp += '&' + u + '=' + opn.query[u];
}
var me = this.getme();
if (opn.type == 'message') {
if (opn.path == app.globalData.sharefirstpage)
param.path = opn.path + '?upid=' + me.id + urlp;
else {
if (app.globalData.sharefirstpage) {
if (urlp[0] == '&')
urlp = '?' + urlp.substring(1);
param.path = app.globalData.sharefirstpage + '?upid=' + me.id + '&u=' + encodeURIComponent(opn.path + urlp);
} else {
param.path = opn.path + '?upid=' + me.id + urlp;
}
}
} else {
param.query = 'upid=' + me.id + urlp;
}
console.log('shareparam', param, opn);
return param;
},
getstrparam(str, split) {
split = split || '|';
var strs = str.split(split);
var ret = {};
for (var i in strs) {
var ind = strs[i].indexOf('=');
if (ind == -1)
continue;
ret[strs[i].substr(0, ind)] = strs[i].substr(ind + 1);
}
return ret;
},
setstrparam(obj, split) {
split = split || '&';
var strs = [];
for (var key in obj)
strs.push(key + '=' + obj[key]);
return strs.join(split);
},
urlparam(url) {
var obj = {};
var ind = url.indexOf('?');
if (ind === -1)
return obj;
var pairs = url.substring(ind + 1).split('&');
for (var p in pairs) {
var ind = pairs[p].indexOf('=');
if (ind > -1)
obj[decodeURIComponent(pairs[p].substring(0, ind))] = decodeURIComponent(pairs[p].substring(ind + 1));
else
obj[pairs[p]] = true;
}
return obj;
},
arrayfind(arr, val, field) {
for (var i in arr) {
if (arr[i][field] == val)
return i;
}
return -1;
},
objdeepmerge(src, desc, btop) {
for (const key in desc) {
if (!desc.hasOwnProperty(key))
continue;
if (desc[key] instanceof Array) {
if (!(src[key] instanceof Array))
src[key] = [];
if (key.substring(0, 4) == 'ciy_')
src[key] = desc[key];
else {
let srcidmap = {};
for (let i in src[key]) {
srcidmap[src[key][i].id] = parseInt(i) + 1;
}
for (let i in desc[key]) {
if (desc[key][i].id && srcidmap[desc[key][i].id]) {
src[key][srcidmap[desc[key][i].id] - 1] = this.objdeepmerge(src[key][srcidmap[desc[key][i].id] - 1], desc[key][i]);
continue;
}
if (btop)
src[key].unshift(desc[key][i]);
else
src[key].push(desc[key][i]);
}
}
} else if (desc[key] instanceof Object) {
src[key] = this.objdeepmerge(src[key] || {}, desc[key]);
} else {
if (src[key] != desc[key])
src[key] = desc[key];
}
}
if (!desc.errmsg && src.errmsg)
delete src.errmsg;
return src;
},
objtolist(list, data) {
if (!list || !data)
return;
if (!this.isarray(list))
return;
if (!this.isobject(data))
return;
let idx = this.arrayfind(list, data.id, 'id');
if (idx == -1)
list.unshift(data);
else
list[idx] = this.objdeepmerge(list[idx], data);
},
objclone(obj) {
if (obj instanceof Date) {
return new Date(obj.getTime());
}
if (obj instanceof Array) {
var clone = [];
for (var i = 0; i < obj.length; i++) {
clone[i] = this.objclone(obj[i]);
}
return clone;
}
if (obj instanceof Object) {
var clone = {};
for (var attr in obj) {
if (obj.hasOwnProperty(attr))
clone[attr] = this.objclone(obj[attr]);
}
return clone;
}
return obj;
},
str2date(str) {
var val = new Date(str.replace(/\-/g, '/'));
if (isNaN(val.getTime()))
return new Date(0);
return val;
},
bin2hex(bin) {
var ret = '';
for (var i = 0, l = bin.length; i < l; i++) {
var c = bin.charCodeAt(i).toString(16);
if (c.length == 1)
c = '0' + c;
ret += c;
}
return ret;
},
hex2bin(hex) {
var ret = '';
for (var i = 0; i < hex.length - 1; i += 2) {
ret += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
}
return ret;
},
style2obj(sty, moresty) {
var styleobj = {};
if (typeof(sty) == 'string') {
sty.split(';').filter(rule => rule.trim() !== '').forEach(rule => {
const [key, value] = rule.split(':').map(part => part.trim());
if (key && value) {
const camelCaseKey = key.replace(/-([a-z])/g, (match, letter) => letter.toUpperCase());
styleobj[camelCaseKey] = value;
}
});
} else {
styleobj = sty || {};
}
if (this.isobject(moresty)) {
for (var i in moresty) {
if (!styleobj[i])
styleobj[i] = moresty[i];
}
}
return styleobj;
},
nopower(mepower, power) {
if (mepower == '.*.') //超级管理员
return false;
power = '.' + power;
var dotidx = -1;
for (let i = 0; i < mepower.length; i++) {
if (mepower[i] !== '.')
continue;
if (dotidx > -1 && dotidx + 1 < i) {
if (power.indexOf(mepower.substring(dotidx, i)) === -1)
continue;
return false; //有权限
}
dotidx = i;
}
return true; //无权限
},
getroute() {
var fpath;
if (this.route)
fpath = '/' + this.route;
else if (this.__route__)
fpath = '/' + this.__route__;
return fpath;
},
com_getpage() {
var thos = this;
for (var i = 0; i < 50; i++) {
if (thos.isPage)
return thos;
thos = thos.$parent;
if (!thos)
return null;
}
return null;
},
async com_gethdft() {
var ret = {
footerheight: 0,
headerheight: 0
};
var compage = this.com_getpage();
if (!compage)
return ret;
var ref = await compage.getrefs('header');
if (ref && ref.Getheight)
ret.headerheight = ref.Getheight();
ref = await compage.getrefs('tabbar');
if (ref && ref.Getheight)
ret.footerheight = ref.Getheight();
else {
var mainrect = await compage.getrect('.tabbar');
if (mainrect)
ret.footerheight = mainrect.height;
}
return ret;
},
async getrefs(refname) {
return new Promise((resolve, reject) => {
var ref = this.getrefsSync(refname);
if (ref !== null) {
resolve(ref);
} else {
setTimeout(() => {
ref = this.getrefsSync(refname);
resolve(ref);
}, 100);
}
}).catch(e => {
return e;
});
},
getrefsSync(refname, compage) {
if (!compage)
compage = this.com_getpage();
if (compage == null)
return null;
if (compage.$refs) {
if (compage.$refs[refname])
return compage.$refs[refname];
}
if (compage.selectComponent) {
var ref = compage.selectComponent('#' + refname);
if (ref)
return ref.$vm;
}
return null;
},
async getrect(dom) {
return new Promise((resolve, reject) => {
this.$nextTick(() => {
uni.createSelectorQuery().in(this).select(dom).boundingClientRect(rect => {
if (rect)
resolve(rect);
else
reject();
}).exec();
});
}).catch(e => {
return e;
});
},
async file_upload1(imgfile, opn) {
return new Promise(async (resolve, reject) => {
if (typeof(imgfile) == 'string')
imgfile = {
tempFilePath: imgfile
};
await this.file_uploads([imgfile], opn, {
success(url, file) {
resolve(url);
},
fail(err, gf, al) {
console.warn(err, gf, al);
reject('Upload Fail:' + err);
}
});
}).catch(e => {
return e;
});
},
async file_uploads(files, opn, fn) { //文件批量上传,图片加水印/压缩/尺寸
//多次返回不能用Promise用fn回调
if (!opn.path) {
opn.basepath = opn.basepath || 'demo';
var now = new Date();
var path = now.getFullYear() + '/' + ('0' + (now.getMonth() + 1)).slice(-2) + ('0' + now.getDate()).slice(-2) + '/' + opn.basepath;
if (opn.saas) {
var saasid = this.toint(opn.saas.substring(1));
path = opn.saas.substring(0, 1) + this.toint(saasid / 1000) + '/' + saasid + '/' + path;
}
opn.path = path;
}
if (opn.action) {
if (opn.action.substring(0, 4) != 'http') {
var uus = opn.action.split('.');
if (uus.length == 1)
uus[1] = this.srv;
opn.action = app.globalData.jsnurl[uus[1]] + 'z/?func=' + uus[0] + '/upload.';
}
} else {
opn.action = app.globalData.jsnurl[app.globalData.srv] + app.globalData.jsnajax + 'upload.';
}
if (typeof(fn.fail) != 'function')
fn.fail = () => {};
opn.waterfont = opn.waterfont || '36px Arial';
for (var u in files) {
(async (gf, tmt) => {
await this.sleep(tmt);
var fpath = gf.tempFilePath || gf.tempImagePath || gf.path;
if (!gf.name)
gf.name = fpath;
if (!this.isimg(gf.name))
return uploadpfile(gf);
// #ifdef H5
var fread = new FileReader();
fread.readAsDataURL(gf);
var err = await this.goe(this.go_load(fread));
if (err)
return fn.fail('FileReader Error', gf, err);
var img = new Image();
img.src = fread.result;
var err = await this.goe(this.go_load(img));
if (err)
return fn.fail('h5Image Load Error', gf, err);
var [width, height] = setimgrect(img);
var zipjpg = this.toint(opn.zipjpg);
if (width == 0 && zipjpg == 0 && !opn.watertext)
return uploadpfile(gf);
if (width == 0) {
width = img.width;
height = img.height;
}
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
var attrw = document.createAttribute("width");
attrw.nodeValue = width;
var attrh = document.createAttribute("height");
attrh.nodeValue = height;
canvas.setAttributeNode(attrw);
canvas.setAttributeNode(attrh);
ctx.drawImage(img, 0, 0, width, height);
waterctx(ctx, width, height);
if (zipjpg == 0)
zipjpg = 70;
var dataurl = canvas.toDataURL("image/jpeg", zipjpg / 100);
var b64s = dataurl.split(",");
var b64type = b64s[0].match(/:(.*?);/)[1];
var ab = atob(b64s[1]);
var ablen = ab.length;
var abarr = new Uint8Array(ablen);
while (ablen--) {
abarr[ablen] = ab.charCodeAt(ablen);
}
uploadpfile(new File([new Blob([abarr], {
type: b64type
})], gf.name));
// #endif
// #ifndef H5
var [err, img] = await this.go(uni.getImageInfo({
src: fpath
}));
if (err)
return fn.fail('getImageInfo Error:' + fpath,
gf, err);
var [width, height] = setimgrect(img);
var zipjpg = this.toint(opn.zipjpg);
if (width == 0 && zipjpg == 0 && !opn.watertext)
return uploadpfile(gf);
if (width == 0) {
width = img.width;
height = img.height;
}
await this.sleep(100);
const canvas = wx.createOffscreenCanvas({
type: '2d',
width: width,
height: height,
});
const fs = uni.getFileSystemManager();
var base64Data = fs.readFileSync(img.path, 'base64');
const ctx = canvas.getContext('2d');
let image = canvas.createImage();
image.src = 'data:image/png;base64,' + base64Data;
var err = await this.goe(this.go_load(image));
if (err)
return fn.fail('Image Load Error', gf, err);
ctx.drawImage(image, 0, 0, width, height);
waterctx(ctx, width, height);
if (zipjpg <= 0)
zipjpg = 70;
var res = await uni.canvasToTempFilePath({
canvas: canvas,
fileType: 'jpg',
quality: zipjpg / 100
});
gf.tempFilePath = res.tempFilePath;
fs.getFileInfo({
filePath: res.tempFilePath,
success: fsize => {
gf.size = fsize.size;
uploadpfile(gf);
}
});
// #endif
})(files[u], 1 + u * 1050);
}
var setimgrect = img => {
var width = 0;
var height = 0;
if (opn.imgwidth > 0) {
if (opn.imgwidth == opn.imgheight) {
width = height = Math.min(img.width, img.height, opn.imgwidth);
} else if (img.width > opn.imgwidth) {
width = opn.imgwidth;
if (opn.imgheight > 0)
height = opn.imgheight;
else
height = width * img.height / img.width;
}
}
return [width, height];
};
var waterctx = (ctx, imgwidth, imgheight) => {
if (!opn.watertext)
return;
if (!this.isarray(opn.watercolors))
opn.watercolors = ['#fffdea', '#000000'];
if (!opn.wateralpha)
opn.wateralpha = 1;
ctx.globalAlpha = this.tofloat(opn.wateralpha);
if (opn.watertype == 'full') {
if (!opn.waterpadding)
opn.waterpadding = 30;
if (!opn.waterangle)
opn.waterangle = -20;
ctx.font = opn.waterfont;
const metrics = ctx.measureText(opn.watertext);
var fontheight = ctx.measureText('啊').width;
const rad = opn.waterangle * Math.PI / 180;
const rotatedWidth = Math.abs(metrics.width * Math.cos(rad)) + Math.abs(fontheight * Math.sin(rad));
const rotatedHeight = Math.abs(metrics.width * Math.sin(rad)) + Math.abs(fontheight * Math.cos(rad));
const itemWidth = rotatedWidth + opn.waterpadding;
const itemHeight = rotatedHeight + opn.waterpadding;
const cols = Math.ceil(imgwidth / itemWidth);
const rows = Math.ceil(imgheight / itemHeight);
const placedWatermarks = [];
for (let i = 0; i < rows * cols * 2; i++) {
const x = Math.random() * (imgwidth - itemWidth);
const y = Math.random() * (imgheight - itemHeight);
let overlap = false;
for (const placed of placedWatermarks) {
const dx = Math.abs(x - placed.x);
const dy = Math.abs(y - placed.y);
if (dx < itemWidth * 0.8 && dy < itemHeight * 0.8) {
overlap = true;
break;
}
}
if (overlap)
continue;
placedWatermarks.push({
x,
y
});
ctx.save();
ctx.translate(x, y);
ctx.rotate((opn.waterangle + Math.random() * 5) * Math.PI / 180);
ctx.fillStyle = opn.watercolors[Math.floor(Math.random() * opn.watercolors.length)];
ctx.fillText(opn.watertext, 0, 0);
ctx.restore();
}
} else {
//右下角多行
ctx.font = opn.waterfont;
var fontheight = ctx.measureText('啊').width * 1.2;
var lines = opn.watertext.split('|');
var y = imgheight - fontheight * lines.length;
for (var i in lines) {
if (opn.watercolors.length > 1) {
ctx.fillStyle = opn.watercolors[1];
ctx.fillText(lines[i], fontheight + 1, y + 1);
ctx.fillText(lines[i], fontheight - 1, y - 1);
ctx.fillText(lines[i], fontheight - 1, y + 1);
ctx.fillText(lines[i], fontheight + 1, y - 1);
}
ctx.fillStyle = opn.watercolors[0];
ctx.fillText(lines[i], fontheight, y);
y += fontheight;
}
}
ctx.globalAlpha = 1;
};
var uploadpfile = async gf => { //文件多通道上传
if (opn.maxkb > 0 && gf.size >= opn.maxkb * 1024)
return fn.fail('MaxSize:' + opn.maxkb + 'KB, This:' + parseInt(gf.size /
1024) + 'KB', gf);
var app = getApp();
var header = {};
header['ciyauth'] = app.getstorage("_" + app.globalData.tokenfield);
var filepath = gf.tempFilePath || gf.tempImagePath || gf.path;
var now = new Date();
var fext = this.file_ext(gf.name);
var pathfile = opn.path + '/' + now.getHours() + now.getMinutes() + now
.getSeconds() + '_' +
(1000 + Math.round(Math.random() * 8000)) + '.' + fext.toLowerCase();
if (opn.stor == '/') {
var ufparam = {};
ufparam.url = opn.action + "upload?pathfile=" + pathfile;
ufparam.header = header;
if (opn.post)
ufparam.formData = opn.post;
if (filepath) {
ufparam.filePath = filepath;
ufparam.name = 'file';
} else {
ufparam.file = gf;
}
var [err, retupfile] = await this.go(uni.uploadFile(ufparam));
if (err)
return fn.fail(err.errMsg, gf, err);
var jsonup = this.json_parse(retupfile.data);
if (jsonup === null)
return fn.fail('JSON Parse ERROR:' + retupfile.data.substr(0, 30),
gf);
if (jsonup.code != 1)
return fn.fail(jsonup.errmsg, gf, jsonup);
if (typeof(fn.success) == 'function')
fn.success(jsonup.url, gf);
} else {
var [err, s3json] = await this.go(this.callfunc({
func: opn.action + "s3?pathfile=" + pathfile +
"&storselect=" + opn.stor
}));
if (err)
return fn.fail(err.errMsg, gf, err);
if (s3json.code != 1)
return fn.fail(s3json.errmsg, gf, s3json);
// #ifdef H5
//H5直接xhr
var xhr = new XMLHttpRequest();
xhr.open(s3json.method, s3json.url, true);
for (var i in s3json.headers) {
xhr.setRequestHeader(i, s3json.headers[i]);
}
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
if (typeof(fn.success) == 'function')
fn.success(opn.stor + pathfile, gf);
} else if (xhr.status != 200) {
fn.fail('云存储上传失败:' + xhr.status, gf, xhr);
}
};
xhr.send(gf);
// #endif
// #ifndef H5
if (app.globalData.stortransfer.includes(opn.stor)) {
var ufparam = {};
ufparam.url = opn.action + "yunsync";
if (s3json.syncurl)
ufparam.url = s3json.syncurl;
s3json.headers = JSON.stringify(s3json.headers);
ufparam.formData = s3json;
if (filepath) {
ufparam.filePath = filepath;
ufparam.name = 'file';
} else {
ufparam.file = gf;
}
var retupfile = await uni.uploadFile(ufparam);
var jsonup = this.json_parse(retupfile.data);
if (jsonup === null)
return fn.fail('JSON Parse ERROR:' + retupfile.data.substr(0,
30), gf, jsonup);
if (jsonup.code != 1)
return fn.fail(jsonup.errmsg, gf, jsonup);
if (typeof(fn.success) == 'function')
fn.success(opn.stor + pathfile, gf);
} else {
console.warn('直传,微信小程序需备案域名,添加域名白名单');
fn.fail('未支持', gf);
}
// #endif
}
};
},
async go(promise) { //var [err, tmp] = await this.go(this.go_load(img));
return promise.then((data) => [null, data]).catch((err) => [err, undefined]);
},
async goe(promise) { //var err = await this.goe(this.go_load(img));
return promise.then(() => null).catch((err) => err);
},
async go_load(obj, act) {
return new Promise((resolve, reject) => {
if (act == 'exec') { //特例
obj.exec(async data => {
resolve(data);
});
} else {
obj.onload = (data) => {
resolve(data);
}
obj.onerror = err => {
console.log('go_load error:', err);
reject('load error');
}
}
});
}
}
});
}
};