智慧教务系统
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

340 lines
9.2 KiB

import {img_domian} from "./config";
import marketApi from '@/api/apiRoute.js';
function formatTime(time) {
if (typeof time !== 'number' || time < 0) {
return time
}
var hour = parseInt(time / 3600)
time = time % 3600
var minute = parseInt(time / 60)
time = time % 60
var second = time
return ([hour, minute, second]).map(function(n) {
n = n.toString()
return n[1] ? n : '0' + n
}).join(':')
}
function formatDateTime(date, fmt = 'yyyy-MM-dd hh:mm:ss') {
if(!date) {
return ''
}
if (typeof (date) === 'number') {
date = new Date(date * 1000)
}
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
}
function formatLocation(longitude, latitude) {
if (typeof longitude === 'string' && typeof latitude === 'string') {
longitude = parseFloat(longitude)
latitude = parseFloat(latitude)
}
longitude = longitude.toFixed(2)
latitude = latitude.toFixed(2)
return {
longitude: longitude.toString().split('.'),
latitude: latitude.toString().split('.')
}
}
var dateUtils = {
UNITS: {
'年': 31557600000,
'月': 2629800000,
'天': 86400000,
'小时': 3600000,
'分钟': 60000,
'秒': 1000
},
humanize: function(milliseconds) {
var humanize = '';
for (var key in this.UNITS) {
if (milliseconds >= this.UNITS[key]) {
humanize = Math.floor(milliseconds / this.UNITS[key]) + key + '前';
break;
}
}
return humanize || '刚刚';
},
format: function(dateStr) {
var date = this.parse(dateStr)
var diff = Date.now() - date.getTime();
if (diff < this.UNITS['天']) {
return this.humanize(diff);
}
var _format = function(number) {
return (number < 10 ? ('0' + number) : number);
};
return date.getFullYear() + '/' + _format(date.getMonth() + 1) + '/' + _format(date.getDate()) + '-' +
_format(date.getHours()) + ':' + _format(date.getMinutes());
},
parse: function(str) { //将"yyyy-mm-dd HH:MM:ss"格式的字符串,转化为一个Date对象
var a = str.split(/[^0-9]/);
return new Date(a[0], a[1] - 1, a[2], a[3], a[4], a[5]);
}
};
const hexToRgba = (hex, opacity) => { //16进制颜色转rgba
return "rgba(" + parseInt("0x" + hex.slice(1, 3)) + "," + parseInt("0x" + hex.slice(3, 5)) + "," + parseInt("0x" + hex.slice(5, 7)) + "," + opacity + ")"
}
/**
* 图片路径转换
* @param {String} img_path 图片地址
* @param {Object} params 参数,针对商品、相册里面的图片区分大中小,size: big、mid、small
*/
function img(img_path, params) {
var path = "";
if (img_path != undefined && img_path != "") {
if (img_path.split(',').length > 1) {
img_path = img_path.split(',')[0];
}
if (params && img_path != getDefaultImage().goods) {
// 过滤默认图
let arr = img_path.split(".");
let suffix = arr[arr.length - 1];
arr.pop();
arr[arr.length - 1] = arr[arr.length - 1] + "_" + params.size.toUpperCase();
arr.push(suffix);
img_path = arr.join(".");
}
if (img_path.indexOf("http://") == -1 && img_path.indexOf("https://") == -1) {
path = img_domian + "/" + img_path;
} else {
path = img_path;
}
if(img_domian.indexOf('https://') != -1){
path = path.replace('http://', 'https://');
}
}
// path += '?t=' + parseInt(new Date().getTime() / 1000);
return path;
}
/**
* 获取默认图
*/
function getDefaultImage() {
let defaultImg = store.state.defaultImg;
defaultImg.goods = img(defaultImg.goods);
defaultImg.head = img(defaultImg.head);
defaultImg.store = img(defaultImg.store);
defaultImg.article = img(defaultImg.article);
return defaultImg;
}
/**
* 时间格式转换
* @param dateTime 如 2024-05-01 01:10:21
* @param fmt 可选参数[Y-m-d H:i:s,Y-m-d,Y-m-d H,Y-m-d H:i,H:i:s,H:i]
* @returns {string}
*/
function formatToDateTime(dateTime, fmt = 'Y-m-d H:i:s') {
if (!dateTime) return ''; // 如果为空,返回空字符串
const date = new Date(dateTime); // 将字符串转换为 Date 对象
// 定义格式化规则
const o = {
'Y+': date.getFullYear(), // 年
'm+': String(date.getMonth() + 1).padStart(2, '0'), // 月
'd+': String(date.getDate()).padStart(2, '0'), // 日
'H+': String(date.getHours()).padStart(2, '0'), // 小时
'i+': String(date.getMinutes()).padStart(2, '0'), // 分钟
's+': String(date.getSeconds()).padStart(2, '0'), // 秒
};
// 替换格式模板中的占位符
for (const k in o) {
if (new RegExp(`(${k})`).test(fmt)) {
fmt = fmt.replace(RegExp.$1, o[k]);
}
}
return fmt;
}
//跳转首页
function openHomeView() {
//获取用户类型缓存
let userType = uni.getStorageSync('userType')
let url_path = ''
switch (String(userType)) {
case '1': //教练
url_path = '/pages/coach/home/index'
break;
case '2': //销售
url_path = '/pages/market/index/index'
break;
case '3': //学员
url_path = '/pages/student/index/index'
break;
default:
uni.showToast({
title: '用户类型错误',
icon: 'none'
})
url_path = '/pages/student/login/login'
return;
}
uni.navigateTo({
url: url_path
})
}
//退出登陆-清空缓存数据
function loginOut() {
//清除token
uni.removeStorageSync('token')
//清除用户信息
uni.removeStorageSync('userInfo')
//清除用户类型
uni.removeStorageSync('userType')
//清除用户角色
uni.removeStorageSync('userRoles')
//清除过期时间
uni.removeStorageSync('expires_time')
//底部菜单选中
uni.removeStorageSync('tabBerIndex')
// 重置Vuex中的用户信息和登录状态
// 注意:在非组件环境中无法直接访问store,需要在组件中调用
// 这里不做store的更新,而是在组件中使用时更新
// 直接跳转到登录页,不显示任何提示信息
uni.reLaunch({
url: '/pages/student/login/login'
})
}
// 全局内存字典缓存
// 使用模块级的变量保存缓存,在整个应用生命周期内都有效
const dictMemoryCache = {};
/**
* 获取字典值,带内存和存储双重缓存
* @param {String} dictKey 字典key
* @returns {Promise<Array|Object>}
*/
async function getDict(dictKey) {
console.log(`getDict - 开始获取字典: ${dictKey}`);
// 先从内存缓存中获取
const now = Date.now();
if (dictMemoryCache[dictKey] && dictMemoryCache[dictKey].expire > now) {
console.log(`getDict - 使用内存缓存: ${dictKey}`);
return dictMemoryCache[dictKey].data;
}
// 内存缓存不存在或已过期,尝试从存储中获取
const cacheKey = `dict_${dictKey}`;
try {
const storageCache = uni.getStorageSync(cacheKey);
if (storageCache && storageCache.data && storageCache.expire > now) {
console.log(`getDict - 使用存储缓存: ${dictKey}`);
// 更新内存缓存
dictMemoryCache[dictKey] = storageCache;
return storageCache.data;
}
} catch (e) {
console.error(`getDict - 读取存储缓存异常: ${dictKey}`, e);
}
console.log(`getDict - 缓存无效,请求接口: ${dictKey}`);
// 缓存不存在或已过期,从服务器获取
try {
// 添加超时处理和重试机制
let retryCount = 0;
const maxRetries = 2;
const fetchWithRetry = async () => {
try {
// 超时控制
const timeoutPromise = new Promise((_, reject) => {
setTimeout(() => reject(new Error(`字典请求超时: ${dictKey}`)), 3000);
});
// 实际API请求
const apiPromise = marketApi.common_Dictionary({ key: dictKey });
// 使用Promise.race来实现超时控制
return await Promise.race([apiPromise, timeoutPromise]);
} catch (error) {
if (retryCount < maxRetries) {
retryCount++;
console.log(`getDict - 重试第${retryCount}次: ${dictKey}`);
return await fetchWithRetry();
}
throw error;
}
};
const res = await fetchWithRetry();
if (res && res.code === 1) {
// 处理接口返回的数据
const formattedData = Array.isArray(res.data) ? res.data : [];
if (formattedData.length > 0) {
// 设置缓存过期时间,默认1小时
const cacheData = {
data: formattedData,
expire: now + 3600 * 1000
};
// 同时更新内存缓存和存储缓存
dictMemoryCache[dictKey] = cacheData;
try {
uni.setStorageSync(cacheKey, cacheData);
} catch (e) {
console.error(`getDict - 存储缓存异常: ${dictKey}`, e);
}
console.log(`getDict - 字典获取成功: ${dictKey}, 条数: ${formattedData.length}`);
} else {
console.warn(`getDict - 字典数据为空: ${dictKey}`);
}
return formattedData;
} else {
console.error(`getDict - API请求失败: ${dictKey}`, res);
return [];
}
} catch (error) {
console.error(`getDict - 异常: ${dictKey}`, error);
return [];
}
}
module.exports = {
loginOut,
openHomeView,
formatTime,
formatDateTime,
formatLocation,
dateUtils,
hexToRgba,
img,
formatToDateTime,
getDict
}