| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469 |
- /**
- * H5版本的字段格式化工具函数
- * 基于小程序版本改造,适配H5环境
- */
- /**
- * 获取字典翻译 - H5版本
- * @param {string} cbName - 字典名称
- * @param {string|number} value - 值
- * @param {string} cacheKey - 缓存键
- * @param {Map} dictCache - 字典缓存
- * @param {Function} updateCallback - 更新回调函数
- */
- const getDictTranslation = async (cbName, value, cacheKey, dictCache, updateCallback) => {
- try {
- console.log(`🔍 获取字典翻译 [${cbName}:${value}]`);
- // 使用 loadObjpOpt 接口调用字典
- const result = await request.post(
- '/service?ssServ=loadObjpOpt&objectpickerdropdown1=1',
- {
- objectpickerparam: JSON.stringify({
- input: "false",
- codebook: cbName
- }),
- objectpickertype: 2, // 2表示获取要回显的一项
- objectpickervalue: value // 需回显的值
- },
- { loading: false, formData: true }
- );
- console.log(`字典翻译 [${cbName}:${value}] API返回:`, result);
- // 处理返回数据格式:{"result":{"622182":"会议室A"}}
- let translatedValue = value; // 默认返回原值
- if (result && result.data && result.data.result) {
- // 从result对象中根据value查找对应的翻译
- translatedValue = result.data.result[value] || value;
- console.log(`字典翻译结果: ${value} -> ${translatedValue}`);
- }
- dictCache.set(cacheKey, translatedValue);
- // 触发页面更新
- if (updateCallback) {
- updateCallback();
- }
- } catch (error) {
- console.error(`字典翻译失败 [${cbName}:${value}]:`, error);
- dictCache.set(cacheKey, value);
- }
- };
- /**
- * 格式化字段值(处理字典翻译、日期格式等)- H5版本
- * @param {Object} fieldObj - 字段对象 {field, value}
- * @param {Map} dictCache - 字典缓存
- * @param {Function} getDictTranslationFn - 字典翻译函数
- * @returns {string} 格式化后的值
- */
- const formatFieldValue = (fieldObj, dictCache, getDictTranslationFn) => {
- if (!fieldObj || !fieldObj.field || fieldObj.value === undefined) {
- return '';
- }
- const { field, value } = fieldObj;
-
- // 空值处理
- if (value === null || value === undefined || value === '') {
- return '';
- }
- // 如果字段有字典配置,进行字典翻译
- if (field.cbName) {
- const cacheKey = `${field.cbName}_${value}`;
-
- // 先从缓存中查找
- if (dictCache.has(cacheKey)) {
- return dictCache.get(cacheKey);
- }
-
- // 缓存中没有,异步获取翻译
- if (getDictTranslationFn) {
- getDictTranslationFn(field.cbName, value, cacheKey, dictCache);
- }
-
- // 返回原值作为临时显示
- return value;
- }
- // 时间格式化(优先检查fmt字段)
- if (field.fmt) {
- return h5FormatDate(value, field.fmt);
- }
- // 日期格式化(兼容旧逻辑)
- if (field.type === 'date' || field.name.toLowerCase().includes('date') ||
- field.name.toLowerCase().includes('time')) {
- return h5FormatDate(value);
- }
- // 数字格式化
- if (field.type === 'number' && typeof value === 'number') {
- return value.toLocaleString();
- }
- // 布尔值格式化
- if (field.type === 'boolean' || typeof value === 'boolean') {
- return value ? '是' : '否';
- }
- // 默认返回字符串
- return String(value);
- };
- /**
- * 解析特殊日期格式:Jul 4, 2025, 6:00:00 AM
- * @param {string} dateStr - 日期字符串
- * @returns {object|null} 解析后的日期对象或null
- */
- const parseSpecialDateFormat = (dateStr) => {
- try {
- // 匹配格式:Jul 4, 2025, 6:00:00 AM
- const regex = /^(\w{3})\s+(\d{1,2}),\s+(\d{4}),\s+(\d{1,2}):(\d{2}):(\d{2})\s+(AM|PM)$/;
- const match = dateStr.match(regex);
- if (!match) return null;
- const [, monthStr, day, year, hour, minute, second, ampm] = match;
- // 月份映射
- const months = {
- 'Jan': 0, 'Feb': 1, 'Mar': 2, 'Apr': 3, 'May': 4, 'Jun': 5,
- 'Jul': 6, 'Aug': 7, 'Sep': 8, 'Oct': 9, 'Nov': 10, 'Dec': 11
- };
- const month = months[monthStr];
- if (month === undefined) return null;
- // 处理12小时制
- let hour24 = parseInt(hour);
- if (ampm === 'PM' && hour24 !== 12) {
- hour24 += 12;
- } else if (ampm === 'AM' && hour24 === 12) {
- hour24 = 0;
- }
- return {
- year: parseInt(year),
- month: month,
- day: parseInt(day),
- hour: hour24,
- minute: parseInt(minute),
- second: parseInt(second)
- };
- } catch (error) {
- console.warn('解析特殊日期格式失败:', dateStr, error);
- return null;
- }
- };
- /**
- * 格式化日期对象
- * @param {object} dateObj - 日期对象 {year, month, day, hour, minute, second}
- * @param {string} format - 格式字符串
- * @returns {string} 格式化后的字符串
- */
- const formatDateObject = (dateObj, format) => {
- const { year, month, day, hour, minute, second } = dateObj;
- return format
- .replace(/YYYY/g, year)
- .replace(/yyyy/g, year)
- .replace(/MM/g, String(month + 1).padStart(2, '0'))
- .replace(/DD/g, String(day).padStart(2, '0'))
- .replace(/dd/g, String(day).padStart(2, '0'))
- .replace(/HH/g, String(hour).padStart(2, '0'))
- .replace(/hh/g, String(hour).padStart(2, '0'))
- .replace(/mm/g, String(minute).padStart(2, '0'))
- .replace(/ss/g, String(second).padStart(2, '0'));
- };
- /**
- * 增强的日期格式化函数 - H5版本
- * @param {string|Date} date - 日期,支持多种格式如 "Jul 4, 2025, 6:00:00 AM"
- * @param {string} format - 格式,如 'YYYY-MM-DD HH:mm:ss'
- * @returns {string} 格式化后的日期
- */
- const h5FormatDate = (date, format = 'YYYY-MM-DD HH:mm:ss') => {
- if (!date) return '';
- try {
- console.log(`🔧 h5FormatDate 开始处理:`, date, '目标格式:', format);
- // 手动解析特殊格式:Jul 4, 2025, 6:00:00 AM
- const parseResult = parseSpecialDateFormat(date);
- if (parseResult) {
- console.log(`🔧 手动解析成功:`, parseResult);
- const result = formatDateObject(parseResult, format);
- console.log(`✅ 手动格式化结果:`, result);
- return result;
- }
- // 使用 Day.js 解析日期(更强大的日期解析能力)
- if (typeof window !== 'undefined' && window.dayjs) {
- const dayObj = window.dayjs(date);
- console.log(`🔧 使用 Day.js 解析:`, dayObj.isValid(), dayObj.toString());
- if (dayObj.isValid()) {
- const result = dayObj.format(format);
- console.log(`✅ Day.js 格式化结果:`, result);
- return result;
- }
- }
- // 降级到原生 Date(如果 Day.js 未加载)
- console.log(`🔧 Day.js 未加载,使用原生 Date`);
- const d = new Date(date);
- console.log(`🔧 解析后的日期对象:`, d, '是否有效:', !isNaN(d.getTime()));
- // 检查日期是否有效
- if (isNaN(d.getTime())) {
- console.warn('❌ 无效日期格式:', date);
- return date; // 无效日期返回原值
- }
- const year = d.getFullYear();
- const month = String(d.getMonth() + 1).padStart(2, '0');
- const day = String(d.getDate()).padStart(2, '0');
- const hours = String(d.getHours()).padStart(2, '0');
- const minutes = String(d.getMinutes()).padStart(2, '0');
- const seconds = String(d.getSeconds()).padStart(2, '0');
- // 支持多种格式模式
- let result = format
- .replace(/YYYY/g, year)
- .replace(/yyyy/g, year)
- .replace(/MM/g, month)
- .replace(/DD/g, day)
- .replace(/dd/g, day)
- .replace(/HH/g, hours)
- .replace(/hh/g, hours)
- .replace(/mm/g, minutes)
- .replace(/ss/g, seconds);
- console.log(`日期格式化: ${date} -> ${result} (格式: ${format})`);
- return result;
- } catch (error) {
- console.error('日期格式化异常:', date, format, error);
- return date; // 异常时返回原值
- }
- };
- /**
- * 异步格式化字段值 - 支持字典转换
- * @param {object} fieldData - 字段数据 {field, value}
- * @param {Map} dictCache - 字典缓存
- * @returns {Promise<string>} 格式化后的值
- */
- const formatFieldValueAsync = async (fieldData, dictCache) => {
- if (!fieldData || !fieldData.field) {
- return fieldData?.value || '';
- }
- const { field, value } = fieldData;
- // 空值处理
- if (value === null || value === undefined || value === '') {
- return '';
- }
- // 优先处理时间格式化(如果字段有fmt属性)
- if (field.fmt) {
- try {
- console.log(`🕐 格式化时间字段 [${field.name}]:`, value, '格式:', field.fmt);
- console.log(`🔧 调用 h5FormatDate 前...`);
- const formattedTime = h5FormatDate(value, field.fmt);
- console.log(`🔧 调用 h5FormatDate 后,结果:`, formattedTime);
- console.log(`✅ 时间格式化结果:`, formattedTime);
- return formattedTime;
- } catch (error) {
- console.error('❌ 时间格式化失败:', field.name, value, error);
- // 格式化失败,返回原值
- return value;
- }
- }
- // 如果字段有字典配置,进行字典转换
- if (field.cbName) {
- const cacheKey = `${field.cbName}_${value}`;
- // 先从缓存中查找
- if (dictCache && dictCache.has(cacheKey)) {
- return dictCache.get(cacheKey);
- }
- // 缓存中没有,异步获取翻译
- try {
- const result = await request.post(
- `/service?ssServ=loadObjpOpt&objectpickerdropdown1=1`,
- {
- objectpickerparam: JSON.stringify({
- input: "false",
- codebook: field.cbName
- }),
- objectpickertype: 2,
- objectpickervalue: value
- },
- {
- loading: false,
- formData: true
- }
- );
- if (result && result.data && result.data.result && result.data.result[value]) {
- const translatedValue = result.data.result[value];
- // 缓存结果
- if (dictCache) {
- dictCache.set(cacheKey, translatedValue);
- }
- return translatedValue;
- }
- } catch (error) {
- console.warn('字典转换失败:', field.cbName, value, error);
- }
- // 转换失败,返回原值
- return value;
- }
- // 日期格式化
- if (field.type === 3 && field.fmt) {
- return h5FormatDate(value, field.fmt);
- }
- // 数字格式化
- if (field.type === 2 && typeof value === 'number') {
- return value.toLocaleString();
- }
- // 默认返回字符串
- return value.toString();
- };
- /**
- * 获取字典所有选项 - 用于下拉菜单
- * @param {string} cbName - 字典名称
- * @param {Map} dictCache - 字典缓存
- * @returns {Promise<Array>} 选项列表 [{n: '显示名', v: '值'}]
- */
- const getDictOptions = async (cbName, dictCache) => {
- const cacheKey = `options_${cbName}`;
- // 检查缓存
- if (dictCache && dictCache.has(cacheKey)) {
- return dictCache.get(cacheKey);
- }
- try {
- console.log(`🔍 获取字典选项 [${cbName}]`);
- const result = await request.post(
- `/service?ssServ=loadObjpOpt&objectpickerdropdown1=1`,
- {
- objectpickerparam: JSON.stringify({
- input: "false",
- codebook: cbName
- }),
- objectpickertype: 1,
- objectpickersearchAll: 1
- },
- {
- loading: false,
- formData: true
- }
- );
- console.log(`字典选项 [${cbName}] API返回:`, result);
- if (result && result.data && result.data.result) {
- const options = Object.entries(result.data.result).map(([value, label]) => ({
- n: label,
- v: value
- }));
- // 缓存结果
- if (dictCache) {
- dictCache.set(cacheKey, options);
- }
- return options;
- }
- return [];
- } catch (error) {
- console.error(`❌ 获取字典选项失败 [${cbName}]:`, error);
- return [];
- }
- };
- /**
- * 格式化对象列表数据 - 处理API返回的objectList
- * @param {Array} objectList - 原始对象列表
- * @param {Map} dictCache - 字典缓存
- * @returns {Promise<Array>} 格式化后的列表
- */
- const formatObjectList = async (objectList, dictCache) => {
- if (!Array.isArray(objectList)) return [];
- const formattedList = [];
- for (const item of objectList) {
- const formattedItem = { ...item };
- // 格式化 first 字段
- if (item.first) {
- formattedItem.firstDisplay = await formatFieldValueAsync(item.first, dictCache);
- }
- // 格式化 second 字段
- if (item.second) {
- formattedItem.secondDisplay = await formatFieldValueAsync(item.second, dictCache);
- }
- // 格式化 third 字段组
- if (item.third && Array.isArray(item.third)) {
- formattedItem.thirdDisplay = [];
- for (const group of item.third) {
- const formattedGroup = [];
- for (const fieldData of group) {
- const displayValue = await formatFieldValueAsync(fieldData, dictCache);
- formattedGroup.push({
- ...fieldData,
- displayValue
- });
- }
- formattedItem.thirdDisplay.push(formattedGroup);
- }
- }
- formattedList.push(formattedItem);
- }
- return formattedList;
- };
- // 导出到全局
- window.H5FieldFormatter = {
- getDictTranslation,
- formatFieldValue,
- formatFieldValueAsync,
- formatDate: h5FormatDate,
- getDictOptions,
- formatObjectList
- };
- // 兼容性:也导出为全局函数
- window.getDictTranslation = getDictTranslation;
- window.formatFieldValue = formatFieldValue;
- window.formatFieldValueAsync = formatFieldValueAsync;
- window.getDictOptions = getDictOptions;
- window.formatObjectList = formatObjectList;
- console.log('✅ H5字段格式化工具加载完成');
|