智慧教务系统
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.
 
 
 
 
 
 

7.4 KiB

字典工具类使用说明

概述

dictUtil.js 是一个专门用于批量获取和缓存字典数据的工具类,解决了原有单个接口调用次数过多、用户体验不佳的问题。

主要功能

  1. 批量获取字典数据 - 一次性获取多个字典,减少接口调用
  2. 智能缓存机制 - 自动缓存数据,避免重复请求
  3. 业务场景支持 - 根据业务场景批量获取相关字典
  4. 兼容性保障 - 保持与原有代码的兼容性

API 接口

后端接口

// 批量获取字典数据
GET /api/dict/batch?keys=key1,key2,key3

// 根据业务场景获取字典
GET /api/dict/scene/{scene}

// 获取单个字典
GET /api/dict/single/{key}

// 获取字典映射关系
GET /api/dict/mapping

// 清除字典缓存
POST /api/dict/clear_cache

前端使用方法

1. 导入工具类

import dictUtil from '@/common/dictUtil.js'

2. 批量获取字典数据

// 方法一:直接批量获取
const dictKeys = ['SourceChannel', 'source', 'customer_purchasing_power']
const dictData = await dictUtil.getBatchDict(dictKeys)

// 结果格式:
// {
//   'SourceChannel': [
//     {name: '抖音', value: '1', sort: 0, memo: ''},
//     {name: '微信', value: '2', sort: 1, memo: ''}
//   ],
//   'source': [...],
//   'customer_purchasing_power': [...]
// }

3. 根据业务场景获取

// 获取客户添加场景的所有字典
const dictData = await dictUtil.getDictByScene('customer_add')

// 或者使用便捷方法
const dictData = await dictUtil.getCustomerAddDict()

4. 单个字典获取

// 获取单个字典(与原有 util.getDict 兼容)
const sourceData = await dictUtil.getDict('source')

5. 预加载字典数据

onLoad() {
  // 在页面加载时预加载,提升用户体验
  const dictKeys = ['SourceChannel', 'source', 'customer_purchasing_power']
  dictUtil.preloadDict(dictKeys)
}

6. 缓存管理

// 清除指定字典缓存
dictUtil.clearCache(['SourceChannel', 'source'])

// 清除所有字典缓存
dictUtil.clearCache()

在页面中的完整使用示例

原有方式(多次接口调用)

// 原有方式 - 问题:多次接口调用,用户体验差
async init() {
  await this.getDict('source_channel')
  await this.getDict('source')
  await this.getDict('purchasing_power')
  await this.getDict('initial_intent')
  await this.getDict('cognitive_idea')
  await this.getDict('status')
  await this.getDict('decision_maker')
  await this.getDict('distance')
}

优化后的方式(批量获取)

// 优化方式 - 一次接口调用获取所有数据
import dictUtil from '@/common/dictUtil.js'

export default {
  onLoad() {
    // 预加载字典数据
    this.preloadDictData()
  },
  
  methods: {
    // 预加载字典数据
    async preloadDictData() {
      const dictKeys = [
        'SourceChannel', 'source', 'customer_purchasing_power', 
        'preliminarycustomerintention', 'cognitive_concept', 
        'kh_status', 'decision_maker', 'distance'
      ]
      
      // 静默预加载,不阻塞页面显示
      dictUtil.preloadDict(dictKeys).catch(error => {
        console.warn('字典预加载失败:', error)
      })
    },

    // 批量获取字典数据
    async getBatchDictData() {
      try {
        uni.showLoading({ title: '加载字典数据...', mask: true })

        const dictKeys = [
          'SourceChannel',                    // 来源渠道
          'source',                          // 来源
          'customer_purchasing_power',       // 购买力
          'preliminarycustomerintention',    // 客户初步意向度
          'cognitive_concept',               // 认知理念
          'kh_status',                      // 客户状态
          'decision_maker',                 // 决策人
          'distance'                        // 距离
        ]

        // 批量获取字典数据
        const dictData = await dictUtil.getBatchDict(dictKeys)
        
        // 处理字典数据
        this.processDictData(dictData)
        
      } catch (error) {
        console.error('批量获取字典数据失败:', error)
        // 如果批量获取失败,回退到单个获取
        await this.fallbackGetDict()
      } finally {
        uni.hideLoading()
      }
    },

    // 处理批量获取的字典数据
    processDictData(dictData) {
      const keyMapping = {
        'SourceChannel': 'source_channel',
        'source': 'source',
        'customer_purchasing_power': 'purchasing_power',
        'preliminarycustomerintention': 'initial_intent',
        'cognitive_concept': 'cognitive_idea',
        'kh_status': 'status',
        'decision_maker': 'decision_maker',
        'distance': 'distance'
      }

      Object.keys(keyMapping).forEach(dictKey => {
        const localKey = keyMapping[dictKey]
        const dictItems = dictData[dictKey] || []

        if (Array.isArray(dictItems) && dictItems.length > 0) {
          const formattedOptions = dictItems.map(item => ({
            text: item.name || '',
            value: item.value || ''
          }))
          
          if (this.picker_config[localKey]) {
            this.picker_config[localKey].options = formattedOptions
          }
        }
      })
    }
  }
}

性能优化特性

1. 缓存机制

  • 自动缓存字典数据到本地存储
  • 缓存有效期 30 分钟
  • 避免重复请求相同数据

2. 批量请求

  • 一次接口调用获取多个字典
  • 减少网络请求次数
  • 提升页面加载速度

3. 预加载策略

  • 页面 onLoad 时预加载数据
  • 不阻塞页面显示
  • 用户操作时数据已就绪

4. 错误处理

  • 批量获取失败时自动回退到单个获取
  • 缓存获取失败时直接请求接口
  • 保证功能的健壮性

兼容性说明

向后兼容

工具类保持与原有 util.getDict() 方法的完全兼容:

// 原有代码无需修改,自动使用新的缓存和批量获取机制
const sourceData = await util.getDict('source')

// 新增的批量获取方法
const batchData = await util.getBatchDict(['source', 'status'])

渐进式升级

可以逐步将页面迁移到新的批量获取方式:

  1. 先导入 dictUtil
  2. onLoad 中添加预加载
  3. init 方法中的多个 getDict 调用替换为一次 getBatchDict 调用

注意事项

  1. 字典 Key 映射:确保后端字典 key 与前端使用的 key 一致
  2. 缓存清理:如果字典数据有更新,记得清理对应缓存
  3. 错误处理:在批量获取失败时,有回退机制保证功能正常
  4. 性能限制:单次最多获取 20 个字典,防止接口性能问题

扩展功能

自定义业务场景

// 在 DictService.php 中添加新的业务场景
public function getDictKeysByScene(string $scene): array
{
    $sceneMapping = [
        'customer_add' => ['SourceChannel', 'source', '...'],
        'personnel_add' => ['gender', 'education', '...'],
        'your_scene' => ['key1', 'key2', '...'] // 添加自定义场景
    ];

    return $sceneMapping[$scene] ?? [];
}

添加新的工具方法

// 在 dictUtil.js 中扩展
dictUtil.getYourSceneDict = async function() {
    return await this.getDictByScene('your_scene')
}

通过这种方式,你可以大幅提升字典数据获取的性能和用户体验。