2024-10-18 15:13:47 +08:00
|
|
|
|
import request from '@/utils/request';
|
2024-10-18 15:30:03 +08:00
|
|
|
|
import {
|
|
|
|
|
|
setStorageWithExpiry,
|
|
|
|
|
|
getStorageWithExpiry
|
|
|
|
|
|
} from '@/utils/auth'
|
2024-10-18 15:13:47 +08:00
|
|
|
|
|
2024-10-18 20:03:26 +08:00
|
|
|
|
export function getWXStatusHeight() {
|
2024-10-09 13:34:36 +08:00
|
|
|
|
// #ifdef MP-WEIXIN
|
|
|
|
|
|
// 获取距上
|
|
|
|
|
|
const barTop = wx.getSystemInfoSync().statusBarHeight
|
|
|
|
|
|
// 获取胶囊按钮位置信息
|
|
|
|
|
|
const menuButtonInfo = wx.getMenuButtonBoundingClientRect()
|
|
|
|
|
|
// 获取导航栏高度
|
|
|
|
|
|
const barHeight = menuButtonInfo.height + (menuButtonInfo.top - barTop) * 2
|
|
|
|
|
|
let barWidth = menuButtonInfo.width
|
|
|
|
|
|
console.log('menuButtonInfo', menuButtonInfo)
|
|
|
|
|
|
let barLeftPosition = 375 - menuButtonInfo.right + menuButtonInfo.width
|
|
|
|
|
|
let menuButtonLeft = menuButtonInfo.left
|
|
|
|
|
|
let menuButtonRight = menuButtonInfo.right
|
|
|
|
|
|
return {
|
|
|
|
|
|
barHeight,
|
|
|
|
|
|
barTop,
|
|
|
|
|
|
barWidth,
|
|
|
|
|
|
barLeftPosition,
|
|
|
|
|
|
menuButtonLeft,
|
|
|
|
|
|
menuButtonRight
|
|
|
|
|
|
}
|
|
|
|
|
|
// #endif
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-10-18 15:13:47 +08:00
|
|
|
|
/**
|
2024-12-09 18:10:47 +08:00
|
|
|
|
* 根据订单的状态获取订单的文字展示状态(这个状态范围少,是按李总意思整理出来的状态)
|
2024-10-18 17:33:53 +08:00
|
|
|
|
* @param ticketsStatus 订单状态
|
2025-01-08 13:52:13 +08:00
|
|
|
|
* @param isHandover 是否交车
|
2024-10-18 15:13:47 +08:00
|
|
|
|
*/
|
2025-09-03 13:22:16 +08:00
|
|
|
|
export function getOrderStatusText(ticketsStatus, isHandover) {
|
2024-12-09 18:10:47 +08:00
|
|
|
|
let str = "已进厂";
|
2025-09-03 13:22:16 +08:00
|
|
|
|
if ("04" == ticketsStatus) {
|
2024-10-18 15:13:47 +08:00
|
|
|
|
//待派工
|
2024-12-05 14:46:37 +08:00
|
|
|
|
str = "待维修"
|
2025-09-03 13:22:16 +08:00
|
|
|
|
} else if ("05" == ticketsStatus) {
|
2024-10-18 15:13:47 +08:00
|
|
|
|
//维修中
|
|
|
|
|
|
str = "维修中"
|
2025-09-03 13:22:16 +08:00
|
|
|
|
} else if ("01" == ticketsStatus) {
|
2024-10-24 16:43:13 +08:00
|
|
|
|
//待取车结算
|
2025-09-03 13:22:16 +08:00
|
|
|
|
if ("1" == isHandover) {
|
2025-01-08 13:52:13 +08:00
|
|
|
|
//已交车
|
|
|
|
|
|
str = "已交车未结算"
|
2025-09-03 13:22:16 +08:00
|
|
|
|
} else {
|
2025-01-08 13:52:13 +08:00
|
|
|
|
//未交车
|
|
|
|
|
|
str = "未交车未结算"
|
|
|
|
|
|
}
|
2025-09-03 13:22:16 +08:00
|
|
|
|
} else if ("06" == ticketsStatus) {
|
2024-10-18 15:13:47 +08:00
|
|
|
|
//挂单/记账
|
2025-09-03 13:22:16 +08:00
|
|
|
|
if ("1" == isHandover) {
|
2025-01-08 13:52:13 +08:00
|
|
|
|
//已交车
|
|
|
|
|
|
str = "已交车已结算"
|
2025-09-03 13:22:16 +08:00
|
|
|
|
} else {
|
2025-01-08 13:52:13 +08:00
|
|
|
|
//未交车
|
|
|
|
|
|
str = "已结算未交车"
|
|
|
|
|
|
}
|
2025-09-03 13:22:16 +08:00
|
|
|
|
} else if ("07" == ticketsStatus) {
|
2024-10-24 16:43:13 +08:00
|
|
|
|
//待通知客户取车
|
2024-12-05 14:46:37 +08:00
|
|
|
|
str = "已竣工"
|
2025-09-03 13:22:16 +08:00
|
|
|
|
} else if ("02" == ticketsStatus) {
|
2024-10-18 15:13:47 +08:00
|
|
|
|
//已结账
|
2025-09-03 13:22:16 +08:00
|
|
|
|
if ("1" == isHandover) {
|
2025-01-08 13:52:13 +08:00
|
|
|
|
//已交车
|
|
|
|
|
|
str = "已交车已结算"
|
2025-09-03 13:22:16 +08:00
|
|
|
|
} else {
|
2025-01-08 13:52:13 +08:00
|
|
|
|
//未交车
|
|
|
|
|
|
str = "已结算未交车"
|
|
|
|
|
|
}
|
2025-09-03 13:22:16 +08:00
|
|
|
|
} else if ("03" == ticketsStatus) {
|
2024-10-18 15:13:47 +08:00
|
|
|
|
//已作废
|
|
|
|
|
|
str = "已作废"
|
2025-09-03 13:22:16 +08:00
|
|
|
|
} else if ("08" == ticketsStatus) {
|
2025-01-08 13:52:13 +08:00
|
|
|
|
//已作废
|
|
|
|
|
|
str = "已完成"
|
2024-10-18 15:13:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
return str;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-12-09 18:10:47 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 根据订单的状态获取订单的文字展示状态(这个状态多,就是系统初始状态)
|
|
|
|
|
|
* @param ticketsStatus 订单状态
|
2025-01-08 13:52:13 +08:00
|
|
|
|
* @param isHandover 是否交车
|
2024-12-09 18:10:47 +08:00
|
|
|
|
*/
|
2025-09-03 13:22:16 +08:00
|
|
|
|
export function getOrderStatusTextAll(ticketsStatus, isHandover) {
|
2024-12-09 18:10:47 +08:00
|
|
|
|
let str = "已进厂";
|
2025-09-03 13:22:16 +08:00
|
|
|
|
if ("04" == ticketsStatus) {
|
2024-12-09 18:10:47 +08:00
|
|
|
|
//待派工
|
|
|
|
|
|
str = "待派工"
|
2025-09-03 13:22:16 +08:00
|
|
|
|
} else if ("05" == ticketsStatus) {
|
2024-12-09 18:10:47 +08:00
|
|
|
|
//维修中
|
|
|
|
|
|
str = "维修中"
|
2025-09-03 13:22:16 +08:00
|
|
|
|
} else if ("01" == ticketsStatus) {
|
2024-12-09 18:10:47 +08:00
|
|
|
|
//待取车结算
|
2025-09-03 13:22:16 +08:00
|
|
|
|
if ("1" == isHandover) {
|
2025-01-08 13:52:13 +08:00
|
|
|
|
//已交车
|
|
|
|
|
|
str = "已交车未结算"
|
2025-09-03 13:22:16 +08:00
|
|
|
|
} else {
|
2025-01-08 13:52:13 +08:00
|
|
|
|
//未交车
|
|
|
|
|
|
str = "未交车未结算"
|
|
|
|
|
|
}
|
2025-09-03 13:22:16 +08:00
|
|
|
|
} else if ("06" == ticketsStatus) {
|
2024-12-09 18:10:47 +08:00
|
|
|
|
//挂单/记账
|
|
|
|
|
|
str = "已挂单/记账待交车"
|
2025-09-03 13:22:16 +08:00
|
|
|
|
if ("1" == isHandover) {
|
2025-01-08 13:52:13 +08:00
|
|
|
|
//已交车
|
|
|
|
|
|
str = "已交车已结算"
|
2025-09-03 13:22:16 +08:00
|
|
|
|
} else {
|
2025-01-08 13:52:13 +08:00
|
|
|
|
//未交车
|
|
|
|
|
|
str = "已结算未交车"
|
|
|
|
|
|
}
|
2025-09-03 13:22:16 +08:00
|
|
|
|
} else if ("07" == ticketsStatus) {
|
2024-12-09 18:10:47 +08:00
|
|
|
|
//待通知客户取车
|
|
|
|
|
|
str = "待通知客户取车"
|
2025-09-03 13:22:16 +08:00
|
|
|
|
} else if ("02" == ticketsStatus) {
|
2024-12-09 18:10:47 +08:00
|
|
|
|
//已结账
|
2025-09-03 13:22:16 +08:00
|
|
|
|
if ("1" == isHandover) {
|
2025-01-08 13:52:13 +08:00
|
|
|
|
//已交车
|
|
|
|
|
|
str = "已交车已结算"
|
2025-09-03 13:22:16 +08:00
|
|
|
|
} else {
|
2025-01-08 13:52:13 +08:00
|
|
|
|
//未交车
|
|
|
|
|
|
str = "已结算未交车"
|
|
|
|
|
|
}
|
2025-09-03 13:22:16 +08:00
|
|
|
|
} else if ("03" == ticketsStatus) {
|
2024-12-09 18:10:47 +08:00
|
|
|
|
//已作废
|
|
|
|
|
|
str = "已作废"
|
2025-09-03 13:22:16 +08:00
|
|
|
|
} else if ("08" == ticketsStatus) {
|
2025-01-08 13:52:13 +08:00
|
|
|
|
//已作废
|
|
|
|
|
|
str = "已完成"
|
2024-12-09 18:10:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
return str;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-10-18 15:13:47 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 查询字典可选值
|
|
|
|
|
|
* @param dictCode
|
|
|
|
|
|
*/
|
2025-09-03 13:22:16 +08:00
|
|
|
|
export function getDictByCode(dictCode) {
|
2024-10-18 15:30:03 +08:00
|
|
|
|
let dictArray = getStorageWithExpiry(dictCode);
|
2025-09-03 13:22:16 +08:00
|
|
|
|
if (null == dictArray || undefined == dictArray) {
|
2024-10-18 15:30:03 +08:00
|
|
|
|
request({
|
|
|
|
|
|
url: '/admin-api/system/dict-data/type',
|
|
|
|
|
|
method: 'get',
|
2025-09-03 13:22:16 +08:00
|
|
|
|
params: {
|
|
|
|
|
|
type: dictCode
|
|
|
|
|
|
}
|
2024-10-18 15:30:03 +08:00
|
|
|
|
}).then((res) => {
|
|
|
|
|
|
console.log(res)
|
|
|
|
|
|
if (res.code == 200) {
|
2025-09-03 13:22:16 +08:00
|
|
|
|
setStorageWithExpiry(dictCode, res.data, 3600)
|
2024-10-18 15:30:03 +08:00
|
|
|
|
return res.data
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
2025-09-03 13:22:16 +08:00
|
|
|
|
} else {
|
2024-10-18 15:30:03 +08:00
|
|
|
|
return dictArray
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-10-18 21:44:30 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 工单记录操作日志
|
|
|
|
|
|
* @param id 工单主表id
|
|
|
|
|
|
* @param ticketsWorkStatus 工单主表状态
|
|
|
|
|
|
* @param itemId 工单子表id
|
|
|
|
|
|
* @param itemStatus 工单子表状态
|
|
|
|
|
|
* @param recordType 操作类型 对应后端枚举:RecordTypeEnum
|
|
|
|
|
|
* @param remark 备注
|
|
|
|
|
|
* @param image 图片相对路径,多个英文逗号隔开
|
2024-10-23 22:15:34 +08:00
|
|
|
|
* @param finishType 完成类型 01:完成并移交下一班组、02:完成并移交总检、03:完成工单
|
|
|
|
|
|
* @param nextName 下一班组名称
|
2024-10-18 21:44:30 +08:00
|
|
|
|
*/
|
2025-09-03 13:22:16 +08:00
|
|
|
|
export function saveTicketsRecords(id, ticketsWorkStatus, itemId, itemStatus, recordType, remark, image, finishType,
|
|
|
|
|
|
nextName) {
|
2024-10-18 21:44:30 +08:00
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
|
|
let dataObj = {
|
|
|
|
|
|
id: id,
|
2025-09-03 13:22:16 +08:00
|
|
|
|
ticketsWorkStatus: ticketsWorkStatus,
|
|
|
|
|
|
item: {
|
|
|
|
|
|
id: itemId,
|
|
|
|
|
|
itemStatus: itemStatus
|
|
|
|
|
|
},
|
2024-10-18 21:44:30 +08:00
|
|
|
|
recordType: recordType,
|
|
|
|
|
|
remark: remark,
|
2025-09-03 13:22:16 +08:00
|
|
|
|
finishType: finishType,
|
|
|
|
|
|
nextName: nextName,
|
2024-10-18 21:44:30 +08:00
|
|
|
|
image: image
|
|
|
|
|
|
}
|
|
|
|
|
|
request({
|
|
|
|
|
|
url: '/admin-api/repair/tickets/updateStatus',
|
|
|
|
|
|
method: 'POST',
|
2025-09-03 13:22:16 +08:00
|
|
|
|
data: dataObj
|
2024-10-18 21:44:30 +08:00
|
|
|
|
}).then((res) => {
|
|
|
|
|
|
console.log(res)
|
|
|
|
|
|
if (res.code == 200) {
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: '操作成功',
|
|
|
|
|
|
icon: 'none'
|
|
|
|
|
|
})
|
|
|
|
|
|
resolve(1);
|
2025-09-03 13:22:16 +08:00
|
|
|
|
} else {
|
2024-10-18 21:44:30 +08:00
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: '操作失败,请联系管理员',
|
|
|
|
|
|
icon: 'none'
|
|
|
|
|
|
})
|
|
|
|
|
|
reject(0);
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2024-10-18 15:30:03 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 翻译字典
|
|
|
|
|
|
* @param dictCode
|
|
|
|
|
|
*/
|
2024-10-22 18:29:31 +08:00
|
|
|
|
export async function getDictTextByCodeAndValue(dictCode, value) {
|
2024-10-18 15:30:03 +08:00
|
|
|
|
let dictArray = getStorageWithExpiry(dictCode);
|
2024-10-22 18:29:31 +08:00
|
|
|
|
if (null == dictArray || undefined == dictArray) {
|
|
|
|
|
|
let res = await request({
|
2024-10-19 10:55:12 +08:00
|
|
|
|
url: '/admin-api/system/dict-data/type',
|
|
|
|
|
|
method: 'get',
|
2025-09-03 13:22:16 +08:00
|
|
|
|
params: {
|
|
|
|
|
|
type: dictCode
|
|
|
|
|
|
}
|
2024-10-19 10:55:12 +08:00
|
|
|
|
})
|
2024-10-22 18:29:31 +08:00
|
|
|
|
if (res.code == 200) {
|
|
|
|
|
|
setStorageWithExpiry(dictCode, res.data, 3600)
|
|
|
|
|
|
dictArray = res.data
|
|
|
|
|
|
let dictObj = dictArray.find(item => item.value == value)
|
|
|
|
|
|
if (dictObj) {
|
|
|
|
|
|
return dictObj.label
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return "未知数据"
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
let dictObj = dictArray.find(item => item.value == value)
|
|
|
|
|
|
if (dictObj) {
|
2024-10-19 18:07:46 +08:00
|
|
|
|
return dictObj.label
|
2024-10-22 18:29:31 +08:00
|
|
|
|
} else {
|
2024-10-19 18:07:46 +08:00
|
|
|
|
return "未知数据"
|
|
|
|
|
|
}
|
2024-10-18 15:30:03 +08:00
|
|
|
|
}
|
2024-10-18 15:13:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-10-18 20:03:26 +08:00
|
|
|
|
export function formatTimestamp(timestamp) {
|
2024-10-17 18:05:11 +08:00
|
|
|
|
// 将时间戳转换为Date对象
|
|
|
|
|
|
const date = new Date(timestamp);
|
|
|
|
|
|
// 获取年月日时分秒
|
|
|
|
|
|
const year = date.getFullYear();
|
|
|
|
|
|
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
|
|
|
|
|
const day = date.getDate().toString().padStart(2, '0');
|
|
|
|
|
|
const hours = date.getHours().toString().padStart(2, '0');
|
|
|
|
|
|
const minutes = date.getMinutes().toString().padStart(2, '0');
|
|
|
|
|
|
const seconds = date.getSeconds().toString().padStart(2, '0');
|
|
|
|
|
|
// 组合成日期时间字符串
|
|
|
|
|
|
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-10-21 18:11:30 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 将时间戳转换为指定格式的日期字符串
|
|
|
|
|
|
* @param {number} timestamp - 时间戳(毫秒)
|
|
|
|
|
|
* @param {string} [format='YYYY-MM-DD'] - 日期格式,默认为 'YYYY-MM-DD'
|
|
|
|
|
|
* @returns {string} - 格式化的日期字符串
|
|
|
|
|
|
*/
|
|
|
|
|
|
export function formatTimestampCustom(timestamp, format = 'YYYY-MM-DD') {
|
|
|
|
|
|
const date = new Date(timestamp);
|
|
|
|
|
|
|
|
|
|
|
|
const year = date.getFullYear();
|
|
|
|
|
|
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
|
|
|
|
|
const day = date.getDate().toString().padStart(2, '0');
|
|
|
|
|
|
const hour = date.getHours().toString().padStart(2, '0');
|
|
|
|
|
|
const minute = date.getMinutes().toString().padStart(2, '0');
|
|
|
|
|
|
const second = date.getSeconds().toString().padStart(2, '0');
|
|
|
|
|
|
|
|
|
|
|
|
const replaceMap = {
|
|
|
|
|
|
'YYYY': year,
|
|
|
|
|
|
'MM': month,
|
|
|
|
|
|
'DD': day,
|
|
|
|
|
|
'HH': hour,
|
|
|
|
|
|
'mm': minute,
|
|
|
|
|
|
'ss': second
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
return format.replace(/YYYY|MM|DD|HH|mm|ss/g, match => replaceMap[match]);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-03 13:22:16 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 格式化金额
|
|
|
|
|
|
* @param {string|number} amount - 金额
|
|
|
|
|
|
* @returns {string} - 格式化后的金额
|
|
|
|
|
|
*/
|
|
|
|
|
|
export function formatCurrency(amount) {
|
|
|
|
|
|
if (amount === undefined || amount === null || amount === '') {
|
|
|
|
|
|
return '0.00';
|
|
|
|
|
|
}
|
|
|
|
|
|
// 处理可能的字符串类型金额
|
|
|
|
|
|
const num = typeof amount === 'string' ? parseFloat(amount) : amount;
|
|
|
|
|
|
// 检查是否是有效数字
|
|
|
|
|
|
if (isNaN(num)) {
|
|
|
|
|
|
return '0.00';
|
|
|
|
|
|
}
|
|
|
|
|
|
// 格式化金额,保留两位小数
|
|
|
|
|
|
return num.toLocaleString('zh-CN', {
|
|
|
|
|
|
minimumFractionDigits: 2,
|
|
|
|
|
|
numberOfDigits: 2
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-10-18 20:03:26 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 组装订单对象
|
|
|
|
|
|
* @param order
|
|
|
|
|
|
*/
|
2024-10-18 20:04:30 +08:00
|
|
|
|
export function builderOrder(order) {
|
2024-10-18 20:03:26 +08:00
|
|
|
|
return {
|
2024-10-18 20:04:30 +08:00
|
|
|
|
id: order.id,
|
|
|
|
|
|
orderNo: order.ticketNo,
|
|
|
|
|
|
flag: 1,
|
|
|
|
|
|
ticketsStatus: order.ticketsStatus,
|
|
|
|
|
|
ticketsWorkStatus: order.ticketsWorkStatus,
|
2025-01-08 13:52:13 +08:00
|
|
|
|
flagStr: getOrderStatusTextAll(order.ticketsStatus, order.isHandover),
|
2024-10-18 20:04:30 +08:00
|
|
|
|
carNum: order.carNo,
|
|
|
|
|
|
nowRepairId: order.nowRepairId,
|
|
|
|
|
|
carModel: order.carBrandName,
|
|
|
|
|
|
userName: order.userName,
|
|
|
|
|
|
userPhone: order.userMobile,
|
|
|
|
|
|
counselorName: order.adviserName,
|
2025-09-03 13:22:16 +08:00
|
|
|
|
canOperate: order.canOperate,
|
2025-01-09 18:03:36 +08:00
|
|
|
|
...order,
|
2024-10-18 20:03:26 +08:00
|
|
|
|
}
|
2024-10-17 18:05:11 +08:00
|
|
|
|
}
|
2024-10-18 20:04:30 +08:00
|
|
|
|
|
|
|
|
|
|
export function formatDate(timestamp) {
|
2025-09-30 09:37:26 +08:00
|
|
|
|
if (!timestamp) {
|
|
|
|
|
|
return ''
|
|
|
|
|
|
}
|
2024-10-18 19:55:06 +08:00
|
|
|
|
// 将时间戳转换为Date对象
|
|
|
|
|
|
const date = new Date(timestamp);
|
|
|
|
|
|
// 获取年月日时分秒
|
|
|
|
|
|
const year = date.getFullYear();
|
|
|
|
|
|
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
|
|
|
|
|
const day = date.getDate().toString().padStart(2, '0');
|
|
|
|
|
|
// 组合成日期时间字符串
|
|
|
|
|
|
return `${year}-${month}-${day}`;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-10-22 11:54:28 +08:00
|
|
|
|
//转换为double
|
|
|
|
|
|
// utils.js
|
|
|
|
|
|
export function convertToDouble(value, decimalPlaces = 1) {
|
|
|
|
|
|
if (value !== undefined && value !== null) {
|
|
|
|
|
|
const parsedValue = parseFloat(value);
|
|
|
|
|
|
if (!isNaN(parsedValue)) {
|
|
|
|
|
|
return parsedValue.toFixed(decimalPlaces);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
console.error('转换失败,值不是有效的数字');
|
|
|
|
|
|
return '0.0'; // 可以设置一个默认值
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
console.error('值不存在');
|
|
|
|
|
|
return '0.0'; // 可以设置一个默认值
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-10-22 15:06:49 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 生成一个16位的纯数字的唯一ID
|
|
|
|
|
|
* 生成策略 head + 当前时间戳 + 随机数
|
|
|
|
|
|
* @param head 前缀
|
|
|
|
|
|
*/
|
|
|
|
|
|
export function createUniqueCodeByHead(head = '') {
|
|
|
|
|
|
const min = 100; // 最小值
|
|
|
|
|
|
const max = 999; // 最大值
|
|
|
|
|
|
return head.toString() + Date.now().toString() + Math.floor(Math.random() * (max - min + 1)) + min;
|
|
|
|
|
|
}
|
2024-10-18 20:04:30 +08:00
|
|
|
|
|
2024-11-25 17:27:01 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 构造树
|
|
|
|
|
|
* @param items 原对象数组
|
|
|
|
|
|
* @param idKey 主标识
|
|
|
|
|
|
* @param parentKey 父标识
|
|
|
|
|
|
* @param mapping 映射Map
|
|
|
|
|
|
*/
|
|
|
|
|
|
export function buildTree(items, idKey, parentKey, mapping = null) {
|
2025-09-03 13:22:16 +08:00
|
|
|
|
const result = []; // 存储最终的树形结构
|
2024-11-25 17:27:01 +08:00
|
|
|
|
const itemMap = {}; // 用于快速查找对象
|
|
|
|
|
|
|
|
|
|
|
|
// 首先将所有项放入map中,便于后续快速查找
|
|
|
|
|
|
for (const item of items) {
|
2025-09-03 13:22:16 +08:00
|
|
|
|
itemMap[item[idKey]] = {
|
|
|
|
|
|
...item,
|
|
|
|
|
|
children: []
|
|
|
|
|
|
};
|
2024-11-25 17:27:01 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 遍历每个项,构建树形结构
|
|
|
|
|
|
for (const item of items) {
|
|
|
|
|
|
const id = item[idKey];
|
|
|
|
|
|
const parentId = item[parentKey];
|
|
|
|
|
|
|
|
|
|
|
|
const node = itemMap[id];
|
|
|
|
|
|
if (parentId !== null && itemMap[parentId]) {
|
|
|
|
|
|
// 如果有父ID,并且父节点存在,则将当前节点加入到其父节点的children数组中
|
|
|
|
|
|
itemMap[parentId].children.push(node);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 如果没有父ID,或者找不到对应的父节点,则认为这是根节点
|
|
|
|
|
|
result.push(node);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-03 13:22:16 +08:00
|
|
|
|
if (mapping) {
|
2024-11-25 17:27:01 +08:00
|
|
|
|
return mapTree(result, mapping)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 映射函数
|
|
|
|
|
|
function mapTree(tree, mapping) {
|
|
|
|
|
|
if (!tree || !Array.isArray(tree)) {
|
|
|
|
|
|
return tree;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const mappedTree = tree.map(item => {
|
|
|
|
|
|
const mappedItem = {};
|
|
|
|
|
|
for (const key in item) {
|
|
|
|
|
|
if (key === 'children') {
|
|
|
|
|
|
// 递归处理 children 数组
|
|
|
|
|
|
if (mapping.children) {
|
|
|
|
|
|
mappedItem[mapping.children] = mapTree(item[key], mapping);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
mappedItem[key] = mapTree(item[key], mapping);
|
|
|
|
|
|
}
|
|
|
|
|
|
} else if (key in mapping) {
|
|
|
|
|
|
// 根据映射规则转换属性
|
|
|
|
|
|
const targetKey = mapping[key];
|
|
|
|
|
|
mappedItem[targetKey] = item[key];
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return mappedItem;
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
return mappedTree;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-11 17:42:50 +08:00
|
|
|
|
export function formatDateChinese(timestamp) {
|
|
|
|
|
|
// 将时间戳转换为Date对象
|
|
|
|
|
|
const date = new Date(timestamp);
|
|
|
|
|
|
// 获取年月日时分秒
|
|
|
|
|
|
const year = date.getFullYear();
|
|
|
|
|
|
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
|
|
|
|
|
const day = date.getDate().toString().padStart(2, '0');
|
|
|
|
|
|
// 组合成日期时间字符串
|
|
|
|
|
|
return `${year}年${month}月${day}日`;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function formatDateTimeToMinute(timestamp) {
|
|
|
|
|
|
// 将时间戳转换为 Date 对象
|
|
|
|
|
|
const date = new Date(timestamp);
|
|
|
|
|
|
// 获取年月日时分
|
|
|
|
|
|
const year = date.getFullYear();
|
|
|
|
|
|
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
|
|
|
|
|
const day = date.getDate().toString().padStart(2, '0');
|
|
|
|
|
|
const hours = date.getHours().toString().padStart(2, '0');
|
|
|
|
|
|
const minutes = date.getMinutes().toString().padStart(2, '0');
|
|
|
|
|
|
// 组合成日期时间字符串(格式:yyyy-MM-dd hh:mm)
|
|
|
|
|
|
return `${year}-${month}-${day} ${hours}:${minutes}`;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-03 13:22:16 +08:00
|
|
|
|
export function getDateRange(type) {
|
|
|
|
|
|
const now = new Date()
|
|
|
|
|
|
let start, end
|
|
|
|
|
|
|
|
|
|
|
|
if (type === 'week') {
|
|
|
|
|
|
// 获取本周的开始(周一)和结束(周日)
|
|
|
|
|
|
const day = now.getDay() || 7 // Sunday 为 0,设为 7
|
|
|
|
|
|
start = new Date(now)
|
|
|
|
|
|
start.setDate(now.getDate() - day + 1)
|
|
|
|
|
|
|
|
|
|
|
|
end = new Date(start)
|
|
|
|
|
|
end.setDate(start.getDate() + 6)
|
|
|
|
|
|
} else if (type === 'month') {
|
|
|
|
|
|
// 获取本月的开始和结束
|
|
|
|
|
|
start = new Date(now.getFullYear(), now.getMonth(), 1)
|
|
|
|
|
|
end = new Date(now.getFullYear(), now.getMonth() + 1, 0) // 本月最后一天
|
|
|
|
|
|
} else if (type === 'day') {
|
|
|
|
|
|
// 获取当天的开始和结束(00:00:00 到 23:59:59)
|
|
|
|
|
|
start = new Date(now)
|
|
|
|
|
|
start.setHours(0, 0, 0, 0)
|
|
|
|
|
|
|
|
|
|
|
|
end = new Date(now)
|
|
|
|
|
|
end.setHours(23, 59, 59, 999)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return []
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return [
|
|
|
|
|
|
formatDateCus(start),
|
|
|
|
|
|
formatDateCus(end)
|
|
|
|
|
|
]
|
|
|
|
|
|
}
|
2024-11-25 17:27:01 +08:00
|
|
|
|
|
2025-09-03 13:22:16 +08:00
|
|
|
|
export function formatDateCus(date) {
|
|
|
|
|
|
const y = date.getFullYear()
|
|
|
|
|
|
const m = (date.getMonth() + 1).toString().padStart(2, '0')
|
|
|
|
|
|
const d = date.getDate().toString().padStart(2, '0')
|
|
|
|
|
|
return `${y}-${m}-${d}`
|
2025-09-30 09:37:26 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 将扁平数组转换为树形结构,并支持按 sort 字段排序
|
|
|
|
|
|
* @param {Array} data 源数据
|
|
|
|
|
|
* @param {String} id 节点ID字段名,默认为 'id'
|
|
|
|
|
|
* @param {String} parentId 父节点ID字段名,默认为 'parentId'
|
|
|
|
|
|
* @param {String} children 子节点字段名,默认为 'children'
|
|
|
|
|
|
* @param {Number|String} rootId 根节点ID值,默认为最小的parentId或0
|
|
|
|
|
|
* @param {String} sortKey 排序字段名,默认为 'sort'
|
|
|
|
|
|
* @returns {Array} 树形结构数据
|
|
|
|
|
|
*/
|
|
|
|
|
|
export function handleTree(data, id, parentId, children, rootId, sortKey) {
|
|
|
|
|
|
// 参数默认值处理
|
|
|
|
|
|
id = id || 'id';
|
|
|
|
|
|
parentId = parentId || 'parentId';
|
|
|
|
|
|
children = children || 'children';
|
|
|
|
|
|
sortKey = sortKey || 'sort';
|
|
|
|
|
|
|
|
|
|
|
|
// 自动计算根节点ID(取最小的parentId,若无则用0)
|
|
|
|
|
|
rootId = rootId || Math.min(...data.map(item => item[parentId])) || 0;
|
|
|
|
|
|
|
|
|
|
|
|
// 深拷贝源数据以避免污染原数组
|
|
|
|
|
|
const cloneData = JSON.parse(JSON.stringify(data));
|
|
|
|
|
|
|
|
|
|
|
|
// 先对所有数据进行排序(确保父节点在前)
|
|
|
|
|
|
cloneData.sort((a, b) => {
|
|
|
|
|
|
const aSort = a[sortKey] ?? 0; // 使用空值合并运算符处理undefined
|
|
|
|
|
|
const bSort = b[sortKey] ?? 0;
|
|
|
|
|
|
return aSort - bSort; // 升序排序
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 构建哈希表加速查找
|
|
|
|
|
|
const nodeMap = {};
|
|
|
|
|
|
cloneData.forEach(item => {
|
|
|
|
|
|
nodeMap[item[id]] = item;
|
|
|
|
|
|
item[children] = []; // 初始化children数组
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 构建树形结构
|
|
|
|
|
|
const tree = [];
|
|
|
|
|
|
cloneData.forEach(item => {
|
|
|
|
|
|
if (item[parentId] === rootId) {
|
|
|
|
|
|
// 根节点直接加入结果
|
|
|
|
|
|
tree.push(item);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 非根节点找到父节点并插入
|
|
|
|
|
|
const parent = nodeMap[item[parentId]];
|
|
|
|
|
|
parent?.[children]?.push(item);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 递归排序所有子节点
|
|
|
|
|
|
const sortChildren = (nodes) => {
|
|
|
|
|
|
nodes.forEach(node => {
|
|
|
|
|
|
if (node[children]?.length) {
|
|
|
|
|
|
node[children].sort((a, b) => {
|
|
|
|
|
|
const aSort = a[sortKey] ?? 0;
|
|
|
|
|
|
const bSort = b[sortKey] ?? 0;
|
|
|
|
|
|
return aSort - bSort;
|
|
|
|
|
|
});
|
|
|
|
|
|
sortChildren(node[children]);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
sortChildren(tree);
|
|
|
|
|
|
|
|
|
|
|
|
return tree.length ? tree : data; // 空树时返回原数据
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 将树形结构数据转成 uniapp multiSelector picker 可用的二维数组
|
|
|
|
|
|
* @param {Array} tree 树形结构数据
|
|
|
|
|
|
* @param {String} labelKey 节点显示字段,默认为 'name'
|
|
|
|
|
|
* @param {String} childrenKey 子节点字段,默认为 'children'
|
|
|
|
|
|
* @returns {Array} picker二维数组,例如 [[一级], [二级], [三级]...]
|
|
|
|
|
|
*/
|
|
|
|
|
|
export function toPickerData(tree, labelKey = 'name', childrenKey = 'children') {
|
|
|
|
|
|
const result = []
|
|
|
|
|
|
|
|
|
|
|
|
function buildColumns(nodes, level = 0) {
|
|
|
|
|
|
if (!nodes || !nodes.length) return
|
|
|
|
|
|
// 当前层级的所有 name
|
|
|
|
|
|
result[level] = nodes.map(n => n[labelKey])
|
|
|
|
|
|
// 默认取第一个子节点继续递归
|
|
|
|
|
|
if (nodes[0][childrenKey] && nodes[0][childrenKey].length) {
|
|
|
|
|
|
buildColumns(nodes[0][childrenKey], level + 1)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
buildColumns(tree, 0)
|
|
|
|
|
|
return result
|
2025-09-03 13:22:16 +08:00
|
|
|
|
}
|