first
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
// ========== COMMON - 公共模块 ==========
|
||||
|
||||
/**
|
||||
* 与后端Terminal枚举一一对应
|
||||
*/
|
||||
export const TerminalEnum = {
|
||||
UNKNOWN: 0, // 未知, 目的:在无法解析到 terminal 时,使用它
|
||||
WECHAT_MINI_PROGRAM: 10, //微信小程序
|
||||
WECHAT_WAP: 11, // 微信公众号
|
||||
H5: 20, // H5 网页
|
||||
APP: 31, // 手机 App
|
||||
};
|
||||
|
||||
/**
|
||||
* 将 uni-app 提供的平台转换为后端所需的 terminal值
|
||||
*
|
||||
* @return 终端
|
||||
*/
|
||||
export const getTerminal = () => {
|
||||
const platformType = uni.getSystemInfoSync().uniPlatform;
|
||||
// 与后端terminal枚举一一对应
|
||||
switch (platformType) {
|
||||
case 'app':
|
||||
return TerminalEnum.APP;
|
||||
case 'web':
|
||||
return TerminalEnum.H5;
|
||||
case 'mp-weixin':
|
||||
return TerminalEnum.WECHAT_MINI_PROGRAM;
|
||||
default:
|
||||
return TerminalEnum.UNKNOWN;
|
||||
}
|
||||
};
|
||||
|
||||
// ========== MALL - 营销模块 ==========
|
||||
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
/**
|
||||
* 优惠类型枚举
|
||||
*/
|
||||
export const PromotionDiscountTypeEnum = {
|
||||
PRICE: {
|
||||
type: 1,
|
||||
name: '满减',
|
||||
},
|
||||
PERCENT: {
|
||||
type: 2,
|
||||
name: '折扣',
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* 优惠劵模板的有限期类型的枚举
|
||||
*/
|
||||
export const CouponTemplateValidityTypeEnum = {
|
||||
DATE: {
|
||||
type: 1,
|
||||
name: '固定日期可用',
|
||||
},
|
||||
TERM: {
|
||||
type: 2,
|
||||
name: '领取之后可用',
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* 营销的商品范围枚举
|
||||
*/
|
||||
export const PromotionProductScopeEnum = {
|
||||
ALL: {
|
||||
scope: 1,
|
||||
name: '通用劵',
|
||||
},
|
||||
SPU: {
|
||||
scope: 2,
|
||||
name: '商品劵',
|
||||
},
|
||||
CATEGORY: {
|
||||
scope: 3,
|
||||
name: '品类劵',
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
// 时间段的状态枚举
|
||||
export const TimeStatusEnum = {
|
||||
WAIT_START: '即将开始',
|
||||
STARTED: '进行中',
|
||||
END: '已结束',
|
||||
};
|
||||
|
||||
/**
|
||||
* 微信小程序的订阅模版
|
||||
*/
|
||||
export const WxaSubscribeTemplate = {
|
||||
TRADE_ORDER_DELIVERY: '订单发货通知',
|
||||
PROMOTION_COMBINATION_SUCCESS: '拼团结果通知',
|
||||
PAY_WALLET_RECHARGER_SUCCESS: '充值成功通知',
|
||||
};
|
||||
export const PromotionActivityTypeEnum = {
|
||||
NORMAL: {
|
||||
type: 0,
|
||||
name: '普通',
|
||||
},
|
||||
SECKILL: {
|
||||
type: 1,
|
||||
name: '秒杀',
|
||||
},
|
||||
BARGAIN: {
|
||||
type: 2,
|
||||
name: '砍价',
|
||||
},
|
||||
COMBINATION: {
|
||||
type: 3,
|
||||
name: '拼团',
|
||||
},
|
||||
POINT: {
|
||||
type: 4,
|
||||
name: '积分商城',
|
||||
},
|
||||
};
|
||||
|
||||
export const getTimeStatusEnum = (startTime, endTime) => {
|
||||
const now = dayjs();
|
||||
if (now.isBefore(startTime)) {
|
||||
return TimeStatusEnum.WAIT_START;
|
||||
} else if (now.isAfter(endTime)) {
|
||||
return TimeStatusEnum.END;
|
||||
} else {
|
||||
return TimeStatusEnum.STARTED;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,25 @@
|
||||
|
||||
/** 终端的枚举 */
|
||||
export const TerminalEnum = {
|
||||
WECHAT_MINI_PROGRAM: {
|
||||
terminal: 10,
|
||||
name: '微信小程序'
|
||||
},
|
||||
|
||||
ALIPAY_APP: {
|
||||
terminal: 40,
|
||||
name: '支付宝小程序'
|
||||
}
|
||||
// WECHAT_WAP: {
|
||||
// terminal: 11,
|
||||
// name: '微信公众号'
|
||||
// },
|
||||
// H5: {
|
||||
// terminal: 20,
|
||||
// name: 'H5 网页'
|
||||
// },
|
||||
// APP: {
|
||||
// terminal: 31,
|
||||
// name: '手机 App'
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
import dayjs from "dayjs";
|
||||
|
||||
/**
|
||||
* 将一个整数转换为分数保留两位小数
|
||||
* @param {number | string | undefined} num 整数
|
||||
* @return {number} 分数
|
||||
*/
|
||||
export const formatToFraction = (num) => {
|
||||
if (typeof num === 'undefined') return 0
|
||||
const parsedNumber = typeof num === 'string' ? parseFloat(num) : num
|
||||
return parseFloat((parsedNumber / 100).toFixed(2))
|
||||
}
|
||||
|
||||
/**
|
||||
* 将一个数转换为 1.00 这样
|
||||
* 数据呈现的时候使用
|
||||
*
|
||||
* @param {number | string | undefined} num 整数
|
||||
* @return {string} 分数
|
||||
*/
|
||||
export const floatToFixed2 = (num) => {
|
||||
let str = '0.00'
|
||||
if (typeof num === 'undefined') {
|
||||
return str
|
||||
}
|
||||
const f = formatToFraction(num)
|
||||
const decimalPart = f.toString().split('.')[1]
|
||||
const len = decimalPart ? decimalPart.length : 0
|
||||
switch (len) {
|
||||
case 0:
|
||||
str = f.toString() + '.00'
|
||||
break
|
||||
case 1:
|
||||
str = f.toString() + '.0'
|
||||
break
|
||||
case 2:
|
||||
str = f.toString()
|
||||
break
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
/**
|
||||
* 将一个分数转换为整数
|
||||
*
|
||||
* @param {number | string | undefined} num 分数
|
||||
* @return {number} 整数
|
||||
*/
|
||||
export const convertToInteger = (num) => {
|
||||
if (typeof num === 'undefined') return 0
|
||||
const parsedNumber = typeof num === 'string' ? parseFloat(num) : num
|
||||
// TODO 分转元后还有小数则四舍五入
|
||||
return Math.round(parsedNumber * 100)
|
||||
}
|
||||
|
||||
/**
|
||||
* 时间日期转换
|
||||
* @param {dayjs.ConfigType} date 当前时间,new Date() 格式
|
||||
* @param {string} format 需要转换的时间格式字符串
|
||||
* @description format 字符串随意,如 `YYYY-mm、YYYY-mm-dd`
|
||||
* @description format 季度:"YYYY-mm-dd HH:MM:SS QQQQ"
|
||||
* @description format 星期:"YYYY-mm-dd HH:MM:SS WWW"
|
||||
* @description format 几周:"YYYY-mm-dd HH:MM:SS ZZZ"
|
||||
* @description format 季度 + 星期 + 几周:"YYYY-mm-dd HH:MM:SS WWW QQQQ ZZZ"
|
||||
* @returns {string} 返回拼接后的时间字符串
|
||||
*/
|
||||
export function formatDate(date, format= 'YYYY-MM-DD HH:mm:ss') {
|
||||
// 日期不存在,则返回空
|
||||
if (!date) {
|
||||
return ''
|
||||
}
|
||||
// 日期存在,则进行格式化
|
||||
if (format === undefined) {
|
||||
format = 'YYYY-MM-DD HH:mm:ss'
|
||||
}
|
||||
return dayjs(date).format(format)
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造树型结构数据
|
||||
*
|
||||
* @param {*} data 数据源
|
||||
* @param {*} id id字段 默认 'id'
|
||||
* @param {*} parentId 父节点字段 默认 'parentId'
|
||||
* @param {*} children 孩子节点字段 默认 'children'
|
||||
* @param {*} rootId 根Id 默认 0
|
||||
*/
|
||||
export function handleTree(data, id = 'id', parentId = 'parentId', children = 'children', rootId = 0) {
|
||||
// 对源数据深度克隆
|
||||
const cloneData = JSON.parse(JSON.stringify(data))
|
||||
// 循环所有项
|
||||
const treeData = cloneData.filter(father => {
|
||||
let branchArr = cloneData.filter(child => {
|
||||
//返回每一项的子级数组
|
||||
return father[id] === child[parentId]
|
||||
});
|
||||
branchArr.length > 0 ? father.children = branchArr : '';
|
||||
//返回第一层
|
||||
return father[parentId] === rootId;
|
||||
});
|
||||
return treeData !== '' ? treeData : data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置分页对象
|
||||
*
|
||||
* TODO 需要处理其它页面
|
||||
*
|
||||
* @param pagination 分页对象
|
||||
*/
|
||||
export function resetPagination(pagination) {
|
||||
pagination.list = [];
|
||||
pagination.total = 0;
|
||||
pagination.pageNo = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将值复制到目标对象,且以目标对象属性为准,例:target: {a:1} source:{a:2,b:3} 结果为:{a:2}
|
||||
* @param target 目标对象
|
||||
* @param source 源对象
|
||||
*/
|
||||
export const copyValueToTarget = (target, source) => {
|
||||
const newObj = Object.assign({}, target, source)
|
||||
// 删除多余属性
|
||||
Object.keys(newObj).forEach((key) => {
|
||||
// 如果不是target中的属性则删除
|
||||
if (Object.keys(target).indexOf(key) === -1) {
|
||||
delete newObj[key]
|
||||
}
|
||||
})
|
||||
// 更新目标对象值
|
||||
Object.assign(target, newObj)
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
class Routine {
|
||||
constructor() {}
|
||||
|
||||
async getCode() {
|
||||
let provider = await this.getProvider();
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.login({
|
||||
provider: provider,
|
||||
scopes: 'auth_user',
|
||||
success(res) {
|
||||
return resolve(res.code);
|
||||
},
|
||||
fail() {
|
||||
return reject(null);
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取服务供应商
|
||||
*/
|
||||
getProvider() {
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.getProvider({
|
||||
service: 'oauth',
|
||||
success(res) {
|
||||
resolve(res.provider);
|
||||
},
|
||||
fail() {
|
||||
resolve(false);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async getUserInfo() {
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.getUserInfo({
|
||||
provider: 'weixin',
|
||||
success: res => {
|
||||
resolve({
|
||||
userInfo: res.userInfo
|
||||
});
|
||||
},
|
||||
fail: (err) => {
|
||||
reject(err);
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default new Routine();
|
||||
@@ -0,0 +1,307 @@
|
||||
// import jsrsasign from 'jsrsasign';
|
||||
import moment from "dayjs";
|
||||
import {
|
||||
TerminalEnum
|
||||
} from "./dict";
|
||||
import routine from "./routine";
|
||||
|
||||
// export const decodeToken = (token) => {
|
||||
// console.log(token)
|
||||
// let obj = null
|
||||
// if (token !== '') {
|
||||
// const payload = jsrsasign.KJUR.jws.JWS.parse(token)
|
||||
// if (payload.hasOwnProperty('payloadObj')) {
|
||||
// obj = payload.payloadObj
|
||||
// }
|
||||
// }
|
||||
// return obj
|
||||
// }
|
||||
|
||||
export function handleIntervalMoney(data) {
|
||||
const obj = {};
|
||||
const timeArr = data.split(";").forEach(item => {
|
||||
if (item) {
|
||||
const t = item.split(":");
|
||||
obj[`${t[0]}:${t[1]}:${t[2]}`] = Number(t[3]);
|
||||
}
|
||||
});
|
||||
return obj;
|
||||
}
|
||||
|
||||
export function getNowIntervalFee(electricityFee, serviceFee) {
|
||||
const obj = JSON.parse(JSON.stringify(electricityFee));
|
||||
const now = {
|
||||
time: '',
|
||||
money: 0
|
||||
}
|
||||
for (const key in serviceFee) {
|
||||
if (obj[key]) {
|
||||
obj[key] += serviceFee[key];
|
||||
} else {
|
||||
obj[key] = serviceFee[key];
|
||||
}
|
||||
}
|
||||
for (const k in obj) {
|
||||
const nowTime = +new Date();
|
||||
const timeArr = k.split('-').map(t => moment(`${moment().format("YYYY-MM-DD")} ${t}`).valueOf());
|
||||
const tmArr = [...timeArr, obj[k]]
|
||||
if (nowTime > tmArr[0] && nowTime <= tmArr[1]) {
|
||||
now.time = k;
|
||||
now.money = now.money + (tmArr[2] || 0)
|
||||
}
|
||||
}
|
||||
now.money = formatValue(now.money, 4, null, false);
|
||||
return now;
|
||||
}
|
||||
|
||||
export function isDefinedAndNotNull(value) {
|
||||
return typeof value !== 'undefined' && value !== null;
|
||||
}
|
||||
|
||||
export function isNumeric(value) {
|
||||
return (value - parseFloat(value) + 1) >= 0;
|
||||
}
|
||||
|
||||
export function formatValue(value, dec, units, showZeroDecimals) {
|
||||
if (isDefinedAndNotNull(value) && isNumeric(value) &&
|
||||
(isDefinedAndNotNull(dec) || isDefinedAndNotNull(units) || Number(value).toString() === value)) {
|
||||
let formatted = Number(value);
|
||||
if (isDefinedAndNotNull(dec)) {
|
||||
formatted = formatted.toFixed(dec);
|
||||
}
|
||||
if (!showZeroDecimals) {
|
||||
formatted = (Number(formatted));
|
||||
}
|
||||
formatted = formatted.toString();
|
||||
if (isDefinedAndNotNull(units) && units.length > 0) {
|
||||
formatted += ' ' + units;
|
||||
}
|
||||
return formatted;
|
||||
} else {
|
||||
return value !== null ? value : '';
|
||||
}
|
||||
}
|
||||
|
||||
export function convertSecondsToTime(stratTs, endTs) {
|
||||
if (!stratTs || !endTs) {
|
||||
return '0分钟'
|
||||
}
|
||||
const seconds = (moment(endTs).valueOf() - moment(stratTs).valueOf()) / 1000 < 0 ? 0 : (moment(endTs).valueOf() -
|
||||
moment(stratTs).valueOf()) / 1000;
|
||||
const hours = Math.floor(seconds / 3600);
|
||||
const minutes = Math.floor((seconds - (hours * 3600)) / 60);
|
||||
let timeString = '';
|
||||
if (hours > 0) {
|
||||
timeString += hours + '小时';
|
||||
}
|
||||
if (minutes > 0 || (hours === 0 && minutes === 0)) {
|
||||
timeString += minutes + '分钟';
|
||||
}
|
||||
|
||||
return timeString.trim();
|
||||
}
|
||||
|
||||
export function showToast(iconType, title) {
|
||||
uni.showToast({
|
||||
icon: iconType,
|
||||
title
|
||||
})
|
||||
}
|
||||
|
||||
export function throttle(func, wait = 50) {
|
||||
// 上一次执行该函数的时间
|
||||
let lastTime = 0;
|
||||
return function(...args) {
|
||||
// 当前时间
|
||||
let now = +new Date();
|
||||
// 将当前时间和上一次执行函数时间对比
|
||||
// 如果差值大于设置的等待时间就执行函数
|
||||
if (now - lastTime > wait) {
|
||||
lastTime = now;
|
||||
func.apply(this, args);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export function handleURL(url) {
|
||||
const reg = /^(http(s)?:\/\/)?([^/]+)\/(.*)$/;
|
||||
const matches = url.match(reg);
|
||||
const protocol = matches[0];
|
||||
const domain = matches[3];
|
||||
const filePath = matches[4];
|
||||
|
||||
return {
|
||||
protocol,
|
||||
domain,
|
||||
filePath
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* 将分转成元
|
||||
*
|
||||
* @param price 分,例如说 100 分
|
||||
* @returns {string} 元,例如说 1.00 元
|
||||
*/
|
||||
export function fen2yuan(price) {
|
||||
return (price / 100.0).toFixed(2)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取终端类型
|
||||
* https://uniapp.dcloud.net.cn/tutorial/platform.html#preprocessor
|
||||
*
|
||||
* @return {number | null} 终端类型
|
||||
*/
|
||||
export async function getTerminal() {
|
||||
let terminal = null;
|
||||
const provior = await routine.getProvider();
|
||||
if (provior.includes('weixin')) {
|
||||
terminal = TerminalEnum.WECHAT_MINI_PROGRAM.terminal
|
||||
} else {
|
||||
terminal = TerminalEnum.ALIPAY_APP.terminal
|
||||
}
|
||||
return terminal;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* opt object | string
|
||||
* to_url object | string
|
||||
* 例:
|
||||
* this.Tips('/pages/test/test'); 跳转不提示
|
||||
* this.Tips({title:'提示'},'/pages/test/test'); 提示并跳转
|
||||
* this.Tips({title:'提示'},{tab:1,url:'/pages/index/index'}); 提示并跳转值table上
|
||||
* tab=1 一定时间后跳转至 table上
|
||||
* tab=2 一定时间后跳转至非 table上
|
||||
* tab=3 一定时间后返回上页面
|
||||
* tab=4 关闭所有页面跳转至非table上
|
||||
* tab=5 关闭当前页面跳转至table上
|
||||
*/
|
||||
export function Tips(opt, to_url) {
|
||||
if (typeof opt == 'string') {
|
||||
to_url = opt;
|
||||
opt = {};
|
||||
}
|
||||
let title = opt.title || '',
|
||||
icon = opt.icon || 'none',
|
||||
endtime = opt.endtime || 2000,
|
||||
success = opt.success;
|
||||
if (title) uni.showToast({
|
||||
title: title,
|
||||
icon: icon,
|
||||
duration: endtime,
|
||||
success
|
||||
})
|
||||
if (to_url != undefined) {
|
||||
if (typeof to_url == 'object') {
|
||||
let tab = to_url.tab || 1,
|
||||
url = to_url.url || '';
|
||||
switch (tab) {
|
||||
case 1:
|
||||
//一定时间后跳转至 table
|
||||
setTimeout(function() {
|
||||
uni.switchTab({
|
||||
url: url
|
||||
})
|
||||
}, endtime);
|
||||
break;
|
||||
case 2:
|
||||
//跳转至非table页面
|
||||
setTimeout(function() {
|
||||
uni.navigateTo({
|
||||
url: url,
|
||||
})
|
||||
}, endtime);
|
||||
break;
|
||||
case 3:
|
||||
//返回上页面
|
||||
setTimeout(function() {
|
||||
// #ifndef H5
|
||||
uni.navigateBack({
|
||||
delta: parseInt(url),
|
||||
})
|
||||
if (to_url.cb) {
|
||||
to_url.cb();
|
||||
}
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
history.back();
|
||||
// #endif
|
||||
}, endtime);
|
||||
break;
|
||||
case 4:
|
||||
//关闭当前所有页面跳转至非table页面
|
||||
setTimeout(function() {
|
||||
uni.reLaunch({
|
||||
url: url,
|
||||
})
|
||||
}, endtime);
|
||||
break;
|
||||
case 5:
|
||||
//关闭当前页面跳转至非table页面
|
||||
setTimeout(function() {
|
||||
uni.redirectTo({
|
||||
url: url,
|
||||
})
|
||||
}, endtime);
|
||||
break;
|
||||
}
|
||||
|
||||
} else if (typeof to_url == 'function') {
|
||||
setTimeout(function() {
|
||||
to_url && to_url();
|
||||
}, endtime);
|
||||
} else {
|
||||
//没有提示时跳转不延迟
|
||||
setTimeout(function() {
|
||||
console.log('to_url222: ', to_url);
|
||||
uni.navigateTo({
|
||||
url: to_url,
|
||||
})
|
||||
}, title ? endtime : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function handleSubmitOrderResultForWxLite(displayContent, type, navigate) {
|
||||
const provior = await routine.getProvider()
|
||||
const parmas = {}
|
||||
if (!provior.includes('alipay')) {
|
||||
const content = type === 'tonglian_app' ? JSON.parse(displayContent || '{}').payinfo : displayContent
|
||||
const payConfig = JSON.parse(content || '{}');
|
||||
parmas['timeStamp'] = payConfig.timeStamp
|
||||
parmas['nonceStr'] = payConfig.nonceStr
|
||||
parmas['package'] = payConfig.packageValue || payConfig.package
|
||||
parmas['signType'] = payConfig.signType
|
||||
parmas['paySign'] = payConfig.paySign
|
||||
} else {
|
||||
parmas['orderInfo'] = displayContent
|
||||
}
|
||||
uni.requestPayment({
|
||||
...parmas,
|
||||
success: res => {
|
||||
// this.showModal = false;
|
||||
// uni.hideLoading();
|
||||
return Tips({
|
||||
title: '支付成功',
|
||||
icon: 'success'
|
||||
}, navigate);
|
||||
},
|
||||
fail: e => {
|
||||
// this.showModal = false;
|
||||
// uni.hideLoading();
|
||||
// 关闭支付的情况
|
||||
if (e.errMsg === 'requestPayment:cancel' ||
|
||||
e.errMsg === 'requestPayment:fail cancel') {
|
||||
return Tips({
|
||||
title: '取消支付'
|
||||
});
|
||||
}
|
||||
return Tips({
|
||||
title: e.errMsg,
|
||||
icon: 'error'
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user