tools.js 4.74 KB
/*
 * @Date: 2022-04-18 15:59:42
 * @LastEditors: hookehuyr hookehuyr@gmail.com
 * @LastEditTime: 2026-01-18 00:18:39
 * @FilePath: /xyxBooking-weapp/src/utils/tools.js
 * @Description: 工具函数库
 */
import dayjs from 'dayjs';
import Taro from '@tarojs/taro';
import BASE_URL, { REQUEST_DEFAULT_PARAMS } from './config'

// 格式化时间
const formatDate = (date) => {
  return dayjs(date).format('YYYY-MM-DD HH:mm');
};

/**
 * @description 判断设备信息
 * @returns {Object} 设备信息对象,包含是否为 Android、iOS、是否为平板等属性
 */
const wxInfo = () => {
  const info = Taro.getSystemInfoSync();
  const isAndroid = info.platform === 'android';
  const isiOS = info.platform === 'ios';
  // 简单模拟
  return {
    isAndroid,
    isiOS,
    isTable: false // 小程序通常不是 tablet 模式,或者可以根据 screenWidth 判断
  };
};

/**
 * @description 解析URL参数
 * @param {*} url
 * @returns {Object} URL参数对象,键值对形式存储参数名和参数值
 */
const parseQueryString = url => {
  if (!url) return {};
  var json = {};
  var arr = url.indexOf('?') >= 0 ? url.substr(url.indexOf('?') + 1).split('&') : [];
  arr.forEach(item => {
    var tmp = item.split('=');
    json[tmp[0]] = tmp[1];
  });
  return json;
}

/**
 * 字符串包含字符数组中字符的状态
 * @param {*} array 字符数组
 * @param {*} str 字符串
 * @returns 包含状态
 */
const strExist = (array, str) => {
  if (!str) return false;
  const exist = array.filter(arr => {
    if (str.indexOf(arr) >= 0) return str;
  })
  return exist.length > 0
}

/**
 * 格式化日期时间字符串,提取开始/结束时间并拼接为「日期 开始时间-结束时间」格式
 * @description 处理包含 begin_time/end_time 的数据对象,截取时间戳最后6位(毫秒/时区等冗余部分),
 *              最终拼接为 "YYYY-MM-DD HH:mm:ss-HH:mm:ss" 格式的字符串
 * @param {Object} data - 包含开始/结束时间的数据源对象
 * @param {string} [data.begin_time] - 开始时间字符串(格式示例:2026-01-13T12:30:45.123456+08:00)
 * @param {string} [data.end_time] - 结束时间字符串(格式同 begin_time)
 * @returns {string} 格式化后的日期时间字符串,格式为「日期 开始时间-结束时间」;若入参无效返回空字符串
 * @example
 * 输入示例
 * const timeData = {
 *   begin_time: '2026-01-13T10:00:00.987654+08:00',
 *   end_time: '2026-01-13T18:30:00.123456+08:00'
 * };
 * 调用函数
 * formatDatetime(timeData); // 返回 "2026-01-13 10:00:00-18:30:00"
 *
 * @example
 * 入参为空的情况
 * formatDatetime(null); // 返回 ""
 * formatDatetime({}); // 返回 ""
 *
 * @note 1. 入参时间字符串需保证前19位为有效格式(YYYY-MM-DDTHH:mm:ss),否则截取后可能出现异常;
 *       2. 若 begin_time/end_time 缺失,拼接后可能出现 "undefined-undefined" 等异常,需保证入参完整性;
 *       3. 该函数默认截取时间字符串前19位(slice(0, -6)),需根据实际时间格式调整截取长度
 */
const formatDatetime = (data) => {
  // 格式化日期
  if (!data || !data.begin_time || !data.end_time) return '';

  // 预处理函数:移除时区后缀,统一格式为 ISO 8601 (YYYY-MM-DDTHH:mm:ss)
  // 这样做是为了让 dayjs 把它当作本地时间处理,避免时区转换导致的时间偏差(始终显示景点当地时间/字面时间)
  const normalize = (timeStr) => {
    if (!timeStr) return '';
    // 移除 +08, +08:00 等时区后缀
    let clean = timeStr.split('+')[0];
    // 移除 Z 后缀
    clean = clean.split('Z')[0];
    // 将空格替换为 T,确保兼容性
    clean = clean.trim().replace(/\s+/, 'T');
    return clean;
  };

  const start = dayjs(normalize(data.begin_time));
  const end = dayjs(normalize(data.end_time));

  if (!start.isValid() || !end.isValid()) return '';

  return `${start.format('YYYY-MM-DD')} ${start.format('HH:mm')}-${end.format('HH:mm')}`;
};

/**
 * @description 构建 API 请求 URL
 * @param {string} action - API 动作名称(如 'get_user_info')
 * @param {Object} [params={}] - 请求参数对象,默认空对象
 * @returns {string} 完整的 API 请求 URL,包含基础路径、动作参数、默认参数和查询字符串
 * @example
 * buildApiUrl('get_user_info', { user_id: 123 });
 * 返回 "/srv/?a=get_user_info&f=json&client_name=xyxBooking&user_id=123"
 */
const buildApiUrl = (action, params = {}) => {
    const queryParams = new URLSearchParams({
        a: action,
        f: REQUEST_DEFAULT_PARAMS.f,
        client_name: REQUEST_DEFAULT_PARAMS.client_name,
        ...params
    })
    return `${BASE_URL}/srv/?${queryParams.toString()}`
}

export { formatDate, wxInfo, parseQueryString, strExist, formatDatetime, buildApiUrl };