feat:转账插件

This commit is contained in:
2026-07-23 14:31:06 +08:00
parent 4916546322
commit d5a6a16ea5
560 changed files with 71777 additions and 44216 deletions
@@ -0,0 +1,64 @@
// 浮点数加法
export function add (arg1, arg2) {
var r1, r2, m
try {
r1 = arg1.toString().split('.')[1].length
} catch (e) {
r1 = 0
}
try {
r2 = arg2.toString().split('.')[1].length
} catch (e) {
r2 = 0
}
m = Math.pow(10, Math.max(r1, r2))
return (arg1 * m + arg2 * m) / m
}
// 浮点数减法
export function sub (arg1, arg2) {
var r1, r2, m, n
try {
r1 = arg1.toString().split('.')[1].length
} catch (e) {
r1 = 0
}
try {
r2 = arg2.toString().split('.')[1].length
} catch (e) {
r2 = 0
}
m = Math.pow(10, Math.max(r1, r2))
n = (r1 >= r2) ? r1 : r2
return Math.abs(((arg1 * m - arg2 * m) / m).toFixed(n))
}
//浮点乘法
export function mul (a, b) {
var c = 0,
d = a.toString(),
e = b.toString();
try {
c += d.split(".")[1].length;
} catch (f) {}
try {
c += e.split(".")[1].length;
} catch (f) {}
return Number(d.replace(".", "")) * Number(e.replace(".", "")) / Math.pow(10, c);
}
//浮点除法
export function div (a, b) {
var c, d, e = 0,
f = 0;
try {
e = a.toString().split(".")[1].length;
} catch (g) {}
try {
f = b.toString().split(".")[1].length;
} catch (g) {}
return c = Number(a.toString().replace(".", "")), d = Number(b.toString().replace(".", "")), xyutil.mul(c / d, Math.pow(10, f - e));
}
export default {
add,
sub,
mul,
div
}
+167 -167
View File
@@ -1,167 +1,167 @@
let _boundaryCheckingState = true; // 是否进行越界检查的全局开关
/**
* 把错误的数据转正
* @private
* @example strip(0.09999999999999998)=0.1
*/
export function strip(num, precision = 15) {
return +parseFloat(Number(num).toPrecision(precision));
}
/**
* Return digits length of a number
* @private
* @param {*number} num Input number
*/
export function digitLength(num) {
// Get digit length of e
const eSplit = num.toString().split(/[eE]/);
const len = (eSplit[0].split('.')[1] || '').length - +(eSplit[1] || 0);
return len > 0 ? len : 0;
}
/**
* 把小数转成整数,如果是小数则放大成整数
* @private
* @param {*number} num 输入数
*/
export function float2Fixed(num) {
if (num.toString().indexOf('e') === -1) {
return Number(num.toString().replace('.', ''));
}
const dLen = digitLength(num);
return dLen > 0 ? strip(Number(num) * Math.pow(10, dLen)) : Number(num);
}
/**
* 检测数字是否越界,如果越界给出提示
* @private
* @param {*number} num 输入数
*/
export function checkBoundary(num) {
if (_boundaryCheckingState) {
if (num > Number.MAX_SAFE_INTEGER || num < Number.MIN_SAFE_INTEGER) {
console.warn(`${num} 超出了精度限制,结果可能不正确`);
}
}
}
/**
* 把递归操作扁平迭代化
* @param {number[]} arr 要操作的数字数组
* @param {function} operation 迭代操作
* @private
*/
export function iteratorOperation(arr, operation) {
const [num1, num2, ...others] = arr;
let res = operation(num1, num2);
others.forEach((num) => {
res = operation(res, num);
});
return res;
}
/**
* 高精度乘法
* @export
*/
export function times(...nums) {
if (nums.length > 2) {
return iteratorOperation(nums, times);
}
const [num1, num2] = nums;
const num1Changed = float2Fixed(num1);
const num2Changed = float2Fixed(num2);
const baseNum = digitLength(num1) + digitLength(num2);
const leftValue = num1Changed * num2Changed;
checkBoundary(leftValue);
return leftValue / Math.pow(10, baseNum);
}
/**
* 高精度加法
* @export
*/
export function plus(...nums) {
if (nums.length > 2) {
return iteratorOperation(nums, plus);
}
const [num1, num2] = nums;
// 取最大的小数位
const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)));
// 把小数都转为整数然后再计算
return (times(num1, baseNum) + times(num2, baseNum)) / baseNum;
}
/**
* 高精度减法
* @export
*/
export function minus(...nums) {
if (nums.length > 2) {
return iteratorOperation(nums, minus);
}
const [num1, num2] = nums;
const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)));
return (times(num1, baseNum) - times(num2, baseNum)) / baseNum;
}
/**
* 高精度除法
* @export
*/
export function divide(...nums) {
if (nums.length > 2) {
return iteratorOperation(nums, divide);
}
const [num1, num2] = nums;
const num1Changed = float2Fixed(num1);
const num2Changed = float2Fixed(num2);
checkBoundary(num1Changed);
checkBoundary(num2Changed);
// 重要,这里必须用strip进行修正
return times(num1Changed / num2Changed, strip(Math.pow(10, digitLength(num2) - digitLength(num1))));
}
/**
* 四舍五入
* @export
*/
export function round(num, ratio) {
const base = Math.pow(10, ratio);
let result = divide(Math.round(Math.abs(times(num, base))), base);
if (num < 0 && result !== 0) {
result = times(result, -1);
}
// 位数不足则补0
return result;
}
/**
* 是否进行边界检查,默认开启
* @param flag 标记开关,true 为开启,false 为关闭,默认为 true
* @export
*/
export function enableBoundaryChecking(flag = true) {
_boundaryCheckingState = flag;
}
export default {
times,
plus,
minus,
divide,
round,
enableBoundaryChecking,
};
let _boundaryCheckingState = true; // 是否进行越界检查的全局开关
/**
* 把错误的数据转正
* @private
* @example strip(0.09999999999999998)=0.1
*/
export function strip(num, precision = 15) {
return +parseFloat(Number(num).toPrecision(precision));
}
/**
* Return digits length of a number
* @private
* @param {*number} num Input number
*/
export function digitLength(num) {
// Get digit length of e
const eSplit = num.toString().split(/[eE]/);
const len = (eSplit[0].split('.')[1] || '').length - +(eSplit[1] || 0);
return len > 0 ? len : 0;
}
/**
* 把小数转成整数,如果是小数则放大成整数
* @private
* @param {*number} num 输入数
*/
export function float2Fixed(num) {
if (num.toString().indexOf('e') === -1) {
return Number(num.toString().replace('.', ''));
}
const dLen = digitLength(num);
return dLen > 0 ? strip(Number(num) * Math.pow(10, dLen)) : Number(num);
}
/**
* 检测数字是否越界,如果越界给出提示
* @private
* @param {*number} num 输入数
*/
export function checkBoundary(num) {
if (_boundaryCheckingState) {
if (num > Number.MAX_SAFE_INTEGER || num < Number.MIN_SAFE_INTEGER) {
console.warn(`${num} 超出了精度限制,结果可能不正确`);
}
}
}
/**
* 把递归操作扁平迭代化
* @param {number[]} arr 要操作的数字数组
* @param {function} operation 迭代操作
* @private
*/
export function iteratorOperation(arr, operation) {
const [num1, num2, ...others] = arr;
let res = operation(num1, num2);
others.forEach((num) => {
res = operation(res, num);
});
return res;
}
/**
* 高精度乘法
* @export
*/
export function times(...nums) {
if (nums.length > 2) {
return iteratorOperation(nums, times);
}
const [num1, num2] = nums;
const num1Changed = float2Fixed(num1);
const num2Changed = float2Fixed(num2);
const baseNum = digitLength(num1) + digitLength(num2);
const leftValue = num1Changed * num2Changed;
checkBoundary(leftValue);
return leftValue / Math.pow(10, baseNum);
}
/**
* 高精度加法
* @export
*/
export function plus(...nums) {
if (nums.length > 2) {
return iteratorOperation(nums, plus);
}
const [num1, num2] = nums;
// 取最大的小数位
const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)));
// 把小数都转为整数然后再计算
return (times(num1, baseNum) + times(num2, baseNum)) / baseNum;
}
/**
* 高精度减法
* @export
*/
export function minus(...nums) {
if (nums.length > 2) {
return iteratorOperation(nums, minus);
}
const [num1, num2] = nums;
const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)));
return (times(num1, baseNum) - times(num2, baseNum)) / baseNum;
}
/**
* 高精度除法
* @export
*/
export function divide(...nums) {
if (nums.length > 2) {
return iteratorOperation(nums, divide);
}
const [num1, num2] = nums;
const num1Changed = float2Fixed(num1);
const num2Changed = float2Fixed(num2);
checkBoundary(num1Changed);
checkBoundary(num2Changed);
// 重要,这里必须用strip进行修正
return times(num1Changed / num2Changed, strip(Math.pow(10, digitLength(num2) - digitLength(num1))));
}
/**
* 四舍五入
* @export
*/
export function round(num, ratio) {
const base = Math.pow(10, ratio);
let result = divide(Math.round(Math.abs(times(num, base))), base);
if (num < 0 && result !== 0) {
result = times(result, -1);
}
// 位数不足则补0
return result;
}
/**
* 是否进行边界检查,默认开启
* @param flag 标记开关,true 为开启,false 为关闭,默认为 true
* @export
*/
export function enableBoundaryChecking(flag = true) {
_boundaryCheckingState = flag;
}
export default {
times,
plus,
minus,
divide,
round,
enableBoundaryChecking,
};
@@ -0,0 +1,4 @@
// 全局挂载引入http相关请求拦截插件
import Request from '../luch-request'
const http = new Request()
export default http
+152 -40
View File
@@ -1,10 +1,10 @@
import {
number as testNumber,
array as testArray,
empty as testEmpty
} from './test'
import { round } from './digit.js'
import config from '../config/config';
import {
number as testNumber,
array as testArray,
empty as testEmpty
} from './test.js'
import { round } from './digit.js'
import config from '../config/config.js'
/**
* @description 如果value小于min,取min;如果value大于max,取max
* @param {number} min
@@ -32,6 +32,20 @@ export function getPx(value, unit = false) {
return unit ? `${parseInt(value)}px` : parseInt(value)
}
/**
* @description 用于统一rpx2px方法,因uni-app现有API未统一。
* @param {number} value 用户传递值的rpx值
* @returns {number}
*/
export function rpx2px(value) {
// #ifdef APP
return uni.upx2px(value)
// #endif
// #ifndef APP
return uni.rpx2px(value)
// #endif
}
/**
* @description 进行延时,以达到可以简写代码的目的 比如: await uni.$u.sleep(20)将会阻塞20ms
* @param {number} value 堵塞时间 单位ms 毫秒
@@ -49,12 +63,12 @@ export function sleep(value = 30) {
* @returns {string} 返回所在平台(小写)
* @link 运行期判断平台 https://uniapp.dcloud.io/frame?id=判断平台
*/
export function os() {
// #ifdef APP || H5 || MP-WEIXIN
return uni.getDeviceInfo().platform.toLowerCase()
// #endif
// #ifndef APP || H5 || MP-WEIXIN
return uni.getSystemInfoSync().platform.toLowerCase()
export function os() {
// #ifdef APP || H5 || MP-WEIXIN
return uni.getDeviceInfo().platform.toLowerCase()
// #endif
// #ifndef APP || H5 || MP-WEIXIN
return uni.getSystemInfoSync().platform.toLowerCase()
// #endif
}
/**
@@ -63,26 +77,26 @@ export function os() {
*/
export function sys() {
return uni.getSystemInfoSync()
}
export function getWindowInfo() {
let ret = {}
// #ifdef APP || H5 || MP-WEIXIN
ret = uni.getWindowInfo()
// #endif
// #ifndef APP || H5 || MP-WEIXIN
ret = sys()
// #endif
return ret
}
export function getDeviceInfo() {
let ret = {}
// #ifdef APP || H5 || MP-WEIXIN
ret = uni.getDeviceInfo()
// #endif
// #ifndef APP || H5 || MP-WEIXIN
ret = sys()
// #endif
return ret
}
export function getWindowInfo() {
let ret = {}
// #ifdef APP || H5 || MP-WEIXIN
ret = uni.getWindowInfo()
// #endif
// #ifndef APP || H5 || MP-WEIXIN
ret = sys()
// #endif
return ret
}
export function getDeviceInfo() {
let ret = {}
// #ifdef APP || H5 || MP-WEIXIN
ret = uni.getDeviceInfo()
// #endif
// #ifndef APP || H5 || MP-WEIXIN
ret = sys()
// #endif
return ret
}
/**
@@ -143,9 +157,14 @@ export function $parent(name = undefined) {
let parent = this.$parent
// 通过while历遍,这里主要是为了H5需要多层解析的问题
while (parent) {
// 父组件
name = name.replace(/up-([a-zA-Z0-9-_]+)/g, 'u-$1')
if (parent.$options && parent.$options.name !== name) {
// 父组件
let name2 = ''
if (name.startsWith('up-')) {
name2 = name.replace(/up-([a-zA-Z0-9-_]+)/g, 'u-$1')
} else if (name.startsWith('u-')) {
name2 = name.replace(/u-([a-zA-Z0-9-_]+)/g, 'up-$1')
}
if (parent.$options && parent.$options.name !== name && parent.$options.name !== name2) {
// 如果组件的name不相等,继续上一级寻找
parent = parent.$parent
} else {
@@ -361,6 +380,10 @@ export function timeFormat(dateTime = null, formatStr = 'yyyy-mm-dd') {
else if (typeof dateTime === 'string' && /^\d+$/.test(dateTime.trim())) {
date = new Date(Number(dateTime))
}
// 检查是否为UTC格式的时间字符串 (2024-12-18T02:25:31.432Z)
else if (typeof dateTime === 'string' && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{1,3})?(Z|[+-]\d{2}:\d{2})?$/.test(dateTime)) {
date = new Date(dateTime)
}
// 其他都认为符合 RFC 2822 规范
else {
// 处理平台性差异,在Safari/Webkit中,new Date仅支持/作为分割符的字符串时间
@@ -627,8 +650,8 @@ export function padZero(value) {
* @param {*} event
*/
export function formValidate(instance, event) {
const formItem = $parent.call(instance, 'u-form-item')
const form = $parent.call(instance, 'u-form')
const formItem = $parent.call(instance, 'up-form-item')
const form = $parent.call(instance, 'up-form')
// 如果发生变化的input或者textarea等,其父组件中有u-form-item或者u-form等,就执行form的validate方法
// 同时将form-item的pros传递给form,让其进行精确对象验证
if (formItem && form) {
@@ -730,12 +753,99 @@ export function getValueByPath(obj, path) {
}, obj);
}
/**
* 生成同色系浅色背景色
* @param {string} textColor - 支持 #RGB、#RRGGBB、rgb()、rgba() 格式
* @param {number} [lightness=85] - 目标亮度百分比(默认85%)
* @returns {string} 十六进制颜色值
*/
export function genLightColor(textColor, lightness = 95) {
// 手动解析颜色值(避免使用document)
const rgb = parseColorWithoutDOM(textColor);
// RGB转HSL色域
const hsl = rgbToHsl(rgb.r, rgb.g, rgb.b);
// 生成浅色背景
const bgHsl = {
h: hsl.h,
s: hsl.s,
l: Math.min(lightness, 95)
};
return hslToHex(bgHsl.h, bgHsl.s, bgHsl.l);
}
/* 手动解析颜色字符串(兼容uni-app环境) */
function parseColorWithoutDOM(colorStr) {
// 统一转小写处理
const str = colorStr.toLowerCase().trim();
// 处理十六进制格式
if (str.startsWith('#')) {
const hex = str.replace('#', '');
const fullHex = hex.length === 3 ?
hex.split('').map(c => c + c).join('') : hex;
return {
r: parseInt(fullHex.substring(0,2), 16),
g: parseInt(fullHex.substring(2,4), 16),
b: parseInt(fullHex.substring(4,6), 16)
};
}
// 处理rgb/rgba格式
const rgbMatch = str.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/);
if (rgbMatch) {
return {
r: +rgbMatch[1],
g: +rgbMatch[2],
b: +rgbMatch[3]
};
}
throw new Error('Invalid color format');
}
// 辅助函数:RGB 转 HSL(色相、饱和度、亮度)
function rgbToHsl(r, g, b) {
r /= 255, g /= 255, b /= 255;
const max = Math.max(r, g, b), min = Math.min(r, g, b);
let h, s, l = (max + min) / 2;
if (max === min) {
h = s = 0; // achromatic
} else {
const d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
case g: h = (b - r) / d + 2; break;
case b: h = (r - g) / d + 4; break;
}
h = (h * 60).toFixed(1);
}
return { h: +h, s: +(s * 100).toFixed(1), l: +(l * 100).toFixed(1) };
}
// 辅助函数:HSL 转十六进制
function hslToHex(h, s, l) {
l /= 100;
const a = s * Math.min(l, 1 - l) / 100;
const f = n => {
const k = (n + h / 30) % 12;
const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
return Math.round(255 * color).toString(16).padStart(2, '0');
};
return `#${f(0)}${f(8)}${f(4)}`;
}
export default {
range,
getPx,
sleep,
os,
sys,
sys,
getWindowInfo,
random,
guid,
@@ -762,5 +872,7 @@ export default {
page,
pages,
getValueByPath,
// setConfig
genLightColor,
rpx2px
}
@@ -1,75 +1,75 @@
/**
* 注意:
* 此部分内容,在vue-cli模式下,需要在vue.config.js加入如下内容才有效:
* module.exports = {
* transpileDependencies: ['uview-v2']
* }
*/
let platform = 'none'
// #ifdef VUE3
platform = 'vue3'
// #endif
// #ifdef VUE2
platform = 'vue2'
// #endif
// #ifdef APP-PLUS
platform = 'plus'
// #endif
// #ifdef APP-NVUE
platform = 'nvue'
// #endif
// #ifdef H5
platform = 'h5'
// #endif
// #ifdef MP
platform = 'mp'
// #endif
// #ifdef MP-WEIXIN
platform = 'weixin'
// #endif
// #ifdef MP-ALIPAY
platform = 'alipay'
// #endif
// #ifdef MP-BAIDU
platform = 'baidu'
// #endif
// #ifdef MP-TOUTIAO
platform = 'toutiao'
// #endif
// #ifdef MP-QQ
platform = 'qq'
// #endif
// #ifdef MP-KUAISHOU
platform = 'kuaishou'
// #endif
// #ifdef MP-360
platform = '360'
// #endif
// #ifdef QUICKAPP-WEBVIEW
platform = 'quickapp-webview'
// #endif
// #ifdef QUICKAPP-WEBVIEW-HUAWEI
platform = 'quickapp-webview-huawei'
// #endif
// #ifdef QUICKAPP-WEBVIEW-UNION
platform = 'quckapp-webview-union'
// #endif
export default platform
/**
* 注意:
* 此部分内容,在vue-cli模式下,需要在vue.config.js加入如下内容才有效:
* module.exports = {
* transpileDependencies: ['uview-v2']
* }
*/
let platform = 'none'
// #ifdef VUE3
platform = 'vue3'
// #endif
// #ifdef VUE2
platform = 'vue2'
// #endif
// #ifdef APP-PLUS
platform = 'plus'
// #endif
// #ifdef APP-NVUE
platform = 'nvue'
// #endif
// #ifdef H5
platform = 'h5'
// #endif
// #ifdef MP
platform = 'mp'
// #endif
// #ifdef MP-WEIXIN
platform = 'weixin'
// #endif
// #ifdef MP-ALIPAY
platform = 'alipay'
// #endif
// #ifdef MP-BAIDU
platform = 'baidu'
// #endif
// #ifdef MP-TOUTIAO
platform = 'toutiao'
// #endif
// #ifdef MP-QQ
platform = 'qq'
// #endif
// #ifdef MP-KUAISHOU
platform = 'kuaishou'
// #endif
// #ifdef MP-360
platform = '360'
// #endif
// #ifdef QUICKAPP-WEBVIEW
platform = 'quickapp-webview'
// #endif
// #ifdef QUICKAPP-WEBVIEW-HUAWEI
platform = 'quickapp-webview-huawei'
// #endif
// #ifdef QUICKAPP-WEBVIEW-UNION
platform = 'quckapp-webview-union'
// #endif
export default platform
+8 -1
View File
@@ -237,6 +237,13 @@ export function object(value) {
return Object.prototype.toString.call(value) === '[object Object]'
}
/**
* 是否是Promise对象
*/
export function objectPromise(value) {
return Object.prototype.toString.call(value) === '[object Promise]';
}
/**
* 是否短信验证码
*/
@@ -257,7 +264,7 @@ export function func(value) {
* @param {Object} value
*/
export function promise(value) {
return object(value) && func(value.then) && func(value.catch)
return objectPromise(value) && func(value.then) && func(value.catch)
}
/** 是否图片格式
@@ -0,0 +1,29 @@
/**
* uni API shims
*
* 部分小程序平台(如支付宝)不支持某些 uni API,直接调用会抛出 TypeError。
* 本模块在库初始化时检测缺失的 API 并自动补齐空实现,防止运行时报错。
*
* 扩展方式:在 needShims 数组中追加 { name, fallback } 即可。
*/
const needShims = [
{
name: 'onWindowResize',
fallback: function (_callback) { /* no-op */ }
},
{
name: 'offWindowResize',
fallback: function (_callback) { /* no-op */ }
}
]
export function applyUniApiShims() {
if (typeof uni === 'undefined') return
for (const { name, fallback } of needShims) {
if (typeof uni[name] !== 'function') {
uni[name] = fallback
}
}
}