Commit cdbf1041 authored by wangxl's avatar wangxl

444

parent a7299ef6
......@@ -913,6 +913,10 @@ export default {
getArrayListByType (params) {
return fetch(`/v1/science-admin/system-parameter/getArrayListByType`, params)
},
// 根据字典类型查询字典数据信息
getDicts (dictType) {
return fetch(`/v1/science-admin/system-parameter/getArrayListByType`, { typeId: dictType })
},
getTreeListByType (params) {
return fetch(`/v1/science-admin/system-parameter/getTreeListByType`, params)
},
......
......@@ -15,6 +15,7 @@ import './views/utils/directives/debounce'
import './views/utils/directives/throttle'
import './views/utils/directives/int'
import { message, modal } from 'ant-design-vue'
import dict from './views/utils/dict'
import * as echarts from 'echarts'
......@@ -36,6 +37,8 @@ Vue.prototype.$ToDoExcel = ToDoExcel;
Vue.prototype.$defaultLength = 5
Vue.prototype.$changeSystemType = changeSystemType
// 注册字典插件
Vue.use(dict)
// 定义全局时间戳过滤器
Vue.filter('formatDate', function (value) {
......
......@@ -56,7 +56,7 @@
<talent-view v-model="id" @close="closeWindow" />
</a-modal>
<a-modal v-model="assignInfoVisible" title="专家评分明细" width="85%" :dialog-style="{ top: '8%' }" :footer="null" destroyOnClose>
<talent-assign-detail v-model="objectId" @close="() => this.assignInfoVisible = false" />
<assign-detail v-model="objectId" @close="() => this.assignInfoVisible = false" />
</a-modal>
</div>
</template>
......@@ -67,12 +67,12 @@ import { isEmptyParams, filterExportExcelData, tableColumnsName } from "@/views/
import talentView from "@/views/report/talent/components/talentView"
import batchAudit from '@/views/audit/talent/batchAudit'
import audit from '@/views/audit/talent/audit'
import talentAssignDetail from '@/views/assign/components/projectAssignDetail'
import assignDetail from '@/views/evaluation/talent/components/assignDetail'
export default {
name: "talentAuditFinal",
components: {
talentView, audit, batchAudit, talentAssignDetail
talentView, audit, batchAudit, assignDetail
},
data () {
return {
......
<template>
<div class="app-content" style="height:70vh;overflow:auto;">
<a-form :form="form" :model="searchForm" layout="inline" class="search_form">
<a-form-item>
<a-input v-model="searchForm.expertName" placeholder="评审专家" :maxLength="100" style="width: 130px" />
</a-form-item>
<a-form-item>
<a-button type="primary" icon="search" @click="search">搜索</a-button>
<a-button type="primary" style="margin-left: 10px" @click="exportData" icon="download">导出</a-button>
</a-form-item>
</a-form>
<a-divider style="height: 1px; background-color: #e8e8e8;" />
<a-table :dataSource="tableData" :columns="columns" rowKey="id" :pagination="false" :loading="loading">
<template slot="talentName" slot-scope="record">
<a-tooltip placement="topLeft">
<template slot="title">
<span>{{ record.personName }}</span>
</template>
<a @click="recordClick(record,'view')">{{record.personName}}</a>
</a-tooltip>
</template>
<template slot="spec" slot-scope="record">
<span v-for="data in record.specList" :key="data.id" :color="'green'">{{data.specName+' '}}</span>
</template>
<template slot="expertEvaluation" slot-scope="record">
<a-tag :color="evaluationColor(record)">{{record.stateName}}</a-tag>
</template>
<template slot="option" slot-scope="record">
<a-button type="link" size="small" @click="recordClick(record,'eView')">查看</a-button>
</template>
</a-table>
<a-pagination v-if="pagination.total > 0" :total="pagination.total" show-size-changer show-quick-jumper v-model="pagination.pageIndex" :page-size="pagination.pageSize" :page-size-options="pagination.pageSizeOptions" @showSizeChange="showSizeChange" @change="change" :showTotal="() => `共 ${pagination.total} 条`" />
<a-modal v-model="visibleView" v-if="visibleView" title="人才详情" width="94%" :footer="null" :dialog-style="{ top: '8%' }" destroyOnClose :maskClosable="false">
<talent-view v-model="talentId" @close="() => this.visibleView = false" />
</a-modal>
<a-modal v-model="visibleEvaluationView" title="专家评分" width="90%" :dialog-style="{ top: '8%' }" :footer="null" destroyOnClose>
<score-view v-model="id" @close="() => this.visibleEvaluationView = false" />
</a-modal>
</div>
</template>
<script>
import moment from 'moment'
import { isEmptyParams, filterExportExcelData, tableColumnsName, } from '@/views/utils/common'
import talentView from '@/views/report/talent/components/talentView'
import scoreView from '@/views/evaluation/talent/components/scoreView'
export default {
name: 'assignDetail',
components: {
talentView, scoreView
},
props: {
value: {
type: String,
default: () => {
return null
}
}
},
data () {
return {
form: this.$form.createForm(this, { name: 'assign_search' }),
searchForm: { talentId: null, expertName: null },
tableData: [],
columns: [
{ title: '专家姓名', dataIndex: 'expertName', align: 'center' },
{ title: '性别', dataIndex: 'expertSex', align: 'center' },
{ title: '职称', dataIndex: 'expertTitleName', align: 'center' },
{ title: '评审专业', dataIndex: 'specNames', align: 'center', ellipsis: true },
{ title: '单位', dataIndex: 'expertUnitName', align: 'center', ellipsis: true },
{ title: '手机号', dataIndex: 'expertMobile', align: 'center' },
{ title: '评分', dataIndex: 'totalScore', align: 'center', width: 60 },
{ title: '评审状态', scopedSlots: { customRender: 'expertEvaluation', colName: 'gradeScore' }, align: 'center' },
],
pagination: { pageIndex: 1, pageSize: this.$defaultPageSize, total: 0, pageSizeOptions: this.$defaultPageSizeOptions },
loading: false,
id: null,
talentId: null,
visibleView: false,
visibleEvaluationView: false,
}
},
created () {
this.getListByPage()
},
methods: {
moment,
getListByPage () {
this.loading = true
this.searchForm.talentId = this.value
let pars = isEmptyParams(this.searchForm)
let par = { ...pars, pageIndex: this.pagination.pageIndex, pageSize: this.pagination.pageSize }
this.$api.talentAssign.getListByPage(par).then(({ data = {} }) => {
if (data) {
const { dataList = [], total = 0 } = data
this.tableData = dataList.map(item => {
return {
...item,
specNames: item.specList ? item.specList.map(e => e.specName).join(',') : ''
}
})
this.pagination.total = total
this.loading = false
}
}).catch(() => { this.loading = false })
},
change () {
this.getListByPage()
},
showSizeChange (current, pageSize) {
this.pagination.pageSize = pageSize
this.getListByPage()
},
search () {
this.pagination.pageIndex = 1
this.getListByPage()
},
reset () {
this.pagination.pageIndex = 1
this.getListByPage()
},
recordClick (record, type) {
if (type === 'view') {
this.talentId = record.talentId
this.visibleView = true
} else if (type === 'eView') {
this.id = record.id
this.visibleEvaluationView = true
}
},
evaluationColor (record) {
let color = ''
switch (record.auditState) {
case 0:
color = '#f50';
break;
case 1:
color = '#2db7f5';
break;
case 2:
color = '#87d068';
break;
}
return color
},
exportData () {
this.loading = true
let column = [
{ title: '专家姓名', dataIndex: 'expertName', align: 'center' },
{ title: '性别', dataIndex: 'expertSex', align: 'center' },
{ title: '职称', dataIndex: 'expertTitleName', align: 'center' },
{ title: '评审专业', dataIndex: 'specNames', align: 'center', ellipsis: true },
{ title: '单位', dataIndex: 'expertUnitName', align: 'center', ellipsis: true },
{ title: '手机号', dataIndex: 'expertMobile', align: 'center' },
{ title: '评分', dataIndex: 'totalScore', align: 'center', width: 60 },
{ title: '评审状态', dataIndex: 'stateName', align: 'center', width: 60 },
]
let pars = isEmptyParams(this.searchForm)
let par = { ...pars, pageIndex: -1, pageSize: -1 }
this.$api.talentAssign.getListByPage(par).then(({ data = {} }) => {
if (data) {
const { dataList = [], total = 0 } = data
dataList.forEach(e => {
e.specNames = e.specList ? e.specList.map(x => x.specName).join(',') : ''
})
this.$ToDoExcel(`人才分配列表`, tableColumnsName(column), filterExportExcelData(column, dataList))
dataList = []
}
this.loading = false
}).catch(() => { this.loading = false })
},
}
}
</script>
import Vue from 'vue'
import api from '@/api'
export default class Dict {
constructor(dict) {
this.dict = dict
}
/**
* 初始化字典数据
* @param {Array} names 字典类型名称数组
* @param {Function} callback 回调函数
*/
async init(names, callback) {
if (names === undefined || names === null) {
throw new Error('need Dict names')
}
const promises = names.map(n => {
// 初始化字典数据结构
Vue.set(this.dict.dictLabel, n, {})
Vue.set(this.dict, n, [])
// 获取字典数据
return api.parameter.getDicts(n).then(res => {
if (res && res.data) {
// 更新字典数据
this.dict[n].splice(0, 0, ...res.data)
// 构建字典标签映射
res.data.forEach(d => {
Vue.set(this.dict.dictLabel[n], d.key, d.title)
})
}
return res
}).catch(error => {
console.error(`获取字典数据失败,类型: ${n}`, error)
return null
})
})
// 等待所有字典数据加载完成
await Promise.all(promises)
// 执行回调函数
if (callback && typeof callback === 'function') {
callback()
}
}
/**
* 获取字典数据
* @param {string} name 字典类型名称
* @returns {Array} 字典数据数组
*/
getDict(name) {
return this.dict[name] || []
}
/**
* 获取字典标签
* @param {string} name 字典类型名称
* @param {string|number} value 字典值
* @returns {string} 字典标签
*/
getDictLabel(name, value) {
return this.dict.dictLabel[name]?.[value] || ''
}
/**
* 刷新字典数据
* @param {string} name 字典类型名称
* @returns {Promise} 刷新结果
*/
async refreshDict(name) {
try {
Vue.set(this.dict.dictLabel, name, {})
Vue.set(this.dict, name, [])
const res = await api.parameter.getDicts(name)
if (res && res.data) {
this.dict[name].splice(0, 0, ...res.data)
res.data.forEach(d => {
Vue.set(this.dict.dictLabel[name], d.key, d.title)
})
}
return res
} catch (error) {
console.error(`刷新字典数据失败,类型: ${name}`, error)
throw error
}
}
/**
* 批量刷新字典数据
* @param {Array} names 字典类型名称数组
* @returns {Promise} 刷新结果
*/
async refreshDicts(names) {
const promises = names.map(name => this.refreshDict(name))
return Promise.all(promises)
}
/**
* 清除字典缓存
* @param {string} name 字典类型名称
*/
clearDict(name) {
Vue.set(this.dict.dictLabel, name, {})
Vue.set(this.dict, name, [])
}
/**
* 清除所有字典缓存
*/
clearAllDicts() {
Object.keys(this.dict).forEach(key => {
if (key !== 'dictLabel') {
Vue.set(this.dict, key, [])
}
})
Vue.set(this.dict, 'dictLabel', {})
}
}
\ No newline at end of file
/**
* 字典类型常量定义
* 用于统一管理系统中所有字典类型的ID
*/
export default {
// 基础字典类型
UNIT_TYPE: 1, // 单位类型
PERSON_TYPE: 2, // 人员类型
PROJECT_TYPE: 3, // 项目类型
TALENT_TYPE: 4, // 人才类型
EXPERT_TYPE: 5, // 专家类型
PARAMETER_TYPE: 6, // 参数类型
EVALUATION_TYPE: 7, // 评估类型
AUDIT_TYPE: 8, // 审核类型
STATUS_TYPE: 9, // 状态类型
// 项目相关
PROJECT_STATUS: 10, // 项目状态
PROJECT_CATEGORY: 11, // 项目分类
PROJECT_LEVEL: 12, // 项目级别
PROJECT_PRIORITY: 13, // 项目优先级
// 任务相关
TASK_STATUS: 20, // 任务状态
TASK_TYPE: 21, // 任务类型
TASK_PRIORITY: 22, // 任务优先级
// 审核相关
AUDIT_STATUS: 30, // 审核状态
AUDIT_TYPE: 31, // 审核类型
AUDIT_RESULT: 32, // 审核结果
// 评估相关
EVALUATION_STATUS: 40, // 评估状态
EVALUATION_TYPE: 41, // 评估类型
EVALUATION_LEVEL: 42, // 评估等级
// 专家相关
EXPERT_SPECIALTY: 50, // 专家专业
EXPERT_LEVEL: 51, // 专家级别
EXPERT_STATUS: 52, // 专家状态
// 系统相关
SYSTEM_PARAMETER: 60, // 系统参数
SYSTEM_CONFIG: 61, // 系统配置
SYSTEM_STATUS: 62, // 系统状态
// 其他
COMMON_STATUS: 100, // 通用状态
COMMON_TYPE: 101, // 通用类型
COMMON_LEVEL: 102, // 通用等级
COMMON_PRIORITY: 103, // 通用优先级
}
/**
* 字典类型描述映射
*/
export const DictTypeLabels = {
1: '单位类型',
2: '人员类型',
3: '项目类型',
4: '人才类型',
5: '专家类型',
6: '参数类型',
7: '评估类型',
8: '审核类型',
9: '状态类型',
10: '项目状态',
11: '项目分类',
12: '项目级别',
13: '项目优先级',
20: '任务状态',
21: '任务类型',
22: '任务优先级',
30: '审核状态',
31: '审核类型',
32: '审核结果',
40: '评估状态',
41: '评估类型',
42: '评估等级',
50: '专家专业',
51: '专家级别',
52: '专家状态',
60: '系统参数',
61: '系统配置',
62: '系统状态',
100: '通用状态',
101: '通用类型',
102: '通用等级',
103: '通用优先级'
}
\ No newline at end of file
# Vue字典系统使用说明
## 概述
基于 [博客文章](https://www.cnblogs.com/domin520Jian/p/18189594) 实现的Vue字典系统,提供了一套完整的字典数据管理解决方案。
## 文件结构
```
src/views/utils/dict/
├── index.js # Vue插件入口文件
├── Dict.js # 字典管理类
├── DictTypes.js # 字典类型常量定义
├── example.vue # 使用示例
└── README.md # 使用说明文档
```
## 快速开始
### 1. 在组件中使用字典
```vue
<template>
<div>
<a-select v-model="status" placeholder="请选择状态">
<a-select-option
v-for="item in dict.projectStatus"
:key="item.key"
:value="item.key"
>
{{ item.title }}
</a-select-option>
</a-select>
<span>状态:{{ getDictLabel('projectStatus', status) }}</span>
</div>
</template>
<script>
export default {
name: "MyComponent",
// 配置需要使用的字典类型
dicts: ['projectStatus', 'taskStatus'],
data() {
return {
status: ''
}
},
mounted() {
// 监听字典数据加载完成事件
this.$on('dictReady', () => {
console.log('字典数据加载完成')
})
}
}
</script>
```
### 2. 字典数据格式
字典数据格式为:
```javascript
[
{
key: '1', // 字典值
title: '进行中', // 字典标签
sort: 1, // 排序
status: 1 // 状态
},
{
key: '2',
title: '已完成',
sort: 2,
status: 1
}
]
```
## API 参考
### 组件选项
- `dicts: Array` - 配置需要使用的字典类型名称数组
### 组件数据
- `dict: Object` - 字典数据对象
- `dict[name]: Array` - 指定类型的字典数据数组
- `dict.dictLabel: Object` - 字典标签映射对象
- `dict.dictLabel[name]: Object` - 指定类型的字典标签映射
### 组件方法
- `getDict(name)` - 获取指定类型的字典数据
- `getDictLabel(name, value)` - 根据值获取字典标签
- `refreshDict(name)` - 刷新指定类型的字典数据
- `refreshDicts(names)` - 批量刷新字典数据
- `clearDict(name)` - 清除指定类型的字典缓存
- `clearAllDicts()` - 清除所有字典缓存
### 组件事件
- `dictReady` - 字典数据加载完成事件
## 字典类型定义
`DictTypes.js` 中定义了系统中常用的字典类型:
```javascript
export default {
// 基础字典类型
UNIT_TYPE: 1, // 单位类型
PERSON_TYPE: 2, // 人员类型
PROJECT_TYPE: 3, // 项目类型
TALENT_TYPE: 4, // 人才类型
EXPERT_TYPE: 5, // 专家类型
PARAMETER_TYPE: 6, // 参数类型
EVALUATION_TYPE: 7, // 评估类型
AUDIT_TYPE: 8, // 审核类型
STATUS_TYPE: 9, // 状态类型
// 项目相关
PROJECT_STATUS: 10, // 项目状态
PROJECT_CATEGORY: 11, // 项目分类
PROJECT_LEVEL: 12, // 项目级别
PROJECT_PRIORITY: 13, // 项目优先级
// 更多类型...
}
```
## 使用示例
### 1. 基本选择器
```vue
<template>
<a-select v-model="value" placeholder="请选择">
<a-select-option
v-for="item in dict.projectStatus"
:key="item.key"
:value="item.key"
>
{{ item.title }}
</a-select-option>
</a-select>
</template>
<script>
export default {
dicts: ['projectStatus'],
data() {
return {
value: ''
}
}
}
</script>
```
### 2. 多选下拉框
```vue
<template>
<a-select v-model="values" mode="multiple" placeholder="请选择多个">
<a-select-option
v-for="item in dict.projectStatus"
:key="item.key"
:value="item.key"
>
{{ item.title }}
</a-select-option>
</a-select>
</template>
<script>
export default {
dicts: ['projectStatus'],
data() {
return {
values: []
}
}
}
</script>
```
### 3. 单选按钮组
```vue
<template>
<a-radio-group v-model="value">
<a-radio
v-for="item in dict.projectStatus"
:key="item.key"
:value="item.key"
>
{{ item.title }}
</a-radio>
</a-radio-group>
</template>
<script>
export default {
dicts: ['projectStatus'],
data() {
return {
value: ''
}
}
}
</script>
```
### 4. 多选按钮组
```vue
<template>
<a-checkbox-group v-model="values">
<a-checkbox
v-for="item in dict.projectStatus"
:key="item.key"
:value="item.key"
>
{{ item.title }}
</a-checkbox>
</a-checkbox-group>
</template>
<script>
export default {
dicts: ['projectStatus'],
data() {
return {
values: []
}
}
}
</script>
```
### 5. 显示字典标签
```vue
<template>
<span>{{ getDictLabel('projectStatus', status) || '未知状态' }}</span>
</template>
<script>
export default {
dicts: ['projectStatus'],
data() {
return {
status: '1'
}
}
}
</script>
```
### 6. 缓存管理
```vue
<template>
<div>
<a-button @click="refreshData">刷新字典</a-button>
<a-button @click="clearCache">清除缓存</a-button>
</div>
</template>
<script>
export default {
dicts: ['projectStatus'],
methods: {
async refreshData() {
try {
await this.refreshDict('projectStatus')
this.$message.success('字典刷新成功')
} catch (error) {
this.$message.error('字典刷新失败')
}
},
clearCache() {
this.clearDict('projectStatus')
this.$message.success('缓存清除成功')
}
}
}
</script>
```
## 高级用法
### 1. 监听字典加载完成
```javascript
mounted() {
this.$on('dictReady', () => {
console.log('字典数据加载完成')
// 可以在这里执行依赖字典数据的逻辑
})
}
```
### 2. 动态刷新字典
```javascript
async refreshProjectStatus() {
await this.refreshDict('projectStatus')
// 字典数据已更新,组件会自动重新渲染
}
```
### 3. 批量操作
```javascript
// 批量刷新多个字典
await this.refreshDicts(['projectStatus', 'taskStatus', 'auditStatus'])
// 清除所有字典缓存
this.clearAllDicts()
```
## 注意事项
1. **字典类型名称**:在 `dicts` 配置中使用的是字典类型名称,不是ID
2. **数据格式**:确保后端返回的字典数据格式包含 `key``title` 字段
3. **异步加载**:字典数据是异步加载的,建议监听 `dictReady` 事件
4. **缓存机制**:字典数据会被缓存,避免重复请求
5. **响应式更新**:使用 `Vue.set` 确保字典数据的响应式更新
## 与原有系统的兼容性
本字典系统完全兼容项目现有的字典API接口:
- 使用 `api.parameter.getArrayListByType` 接口获取字典数据
- 保持原有的数据格式和字段名称
- 可以与现有的字典缓存系统并存
## 参考链接
- [Vue中dicts怎么使用](https://www.cnblogs.com/domin520Jian/p/18189594)
\ No newline at end of file
<template>
<div class="dict-example">
<h2>字典系统使用示例</h2>
<!-- 基本使用示例 -->
<div class="section">
<h3>1. 基本使用</h3>
<div class="demo-item">
<label>项目状态选择:</label>
<a-select v-model="projectStatus" placeholder="请选择项目状态" style="width: 200px">
<a-select-option
v-for="item in dict.projectStatus"
:key="item.key"
:value="item.key"
>
{{ item.title }}
</a-select-option>
</a-select>
<span class="result">选中值:{{ projectStatus }}</span>
</div>
<div class="demo-item">
<label>项目状态标签:</label>
<span>{{ getDictLabel('projectStatus', projectStatus) || '未知状态' }}</span>
</div>
</div>
<!-- 多选示例 -->
<div class="section">
<h3>2. 多选使用</h3>
<div class="demo-item">
<label>多选项目状态:</label>
<a-select v-model="multipleStatus" mode="multiple" placeholder="请选择多个状态" style="width: 300px">
<a-select-option
v-for="item in dict.projectStatus"
:key="item.key"
:value="item.key"
>
{{ item.title }}
</a-select-option>
</a-select>
<span class="result">选中值:{{ multipleStatus }}</span>
</div>
</div>
<!-- 按钮组示例 -->
<div class="section">
<h3>3. 按钮组</h3>
<div class="demo-item">
<label>单选按钮:</label>
<a-radio-group v-model="radioValue">
<a-radio
v-for="item in dict.projectStatus"
:key="item.key"
:value="item.key"
>
{{ item.title }}
</a-radio>
</a-radio-group>
<span class="result">选中值:{{ radioValue }}</span>
</div>
<div class="demo-item">
<label>多选按钮:</label>
<a-checkbox-group v-model="checkboxValues">
<a-checkbox
v-for="item in dict.projectStatus"
:key="item.key"
:value="item.key"
>
{{ item.title }}
</a-checkbox>
</a-checkbox-group>
<span class="result">选中值:{{ checkboxValues }}</span>
</div>
</div>
<!-- 缓存管理示例 -->
<div class="section">
<h3>4. 缓存管理</h3>
<div class="demo-item">
<a-button @click="refreshProjectStatus">刷新项目状态</a-button>
<a-button @click="clearProjectStatus">清除项目状态缓存</a-button>
<a-button @click="clearAllDicts">清除所有缓存</a-button>
</div>
</div>
<!-- 字典数据展示 -->
<div class="section">
<h3>5. 字典数据展示</h3>
<div class="demo-item">
<h4>项目状态字典数据:</h4>
<pre>{{ JSON.stringify(dict.projectStatus, null, 2) }}</pre>
</div>
<div class="demo-item">
<h4>字典标签映射:</h4>
<pre>{{ JSON.stringify(dict.dictLabel.projectStatus, null, 2) }}</pre>
</div>
</div>
</div>
</template>
<script>
import { DictTypes } from './DictTypes'
export default {
name: 'DictExample',
// 配置需要使用的字典类型
dicts: ['projectStatus', 'taskStatus', 'auditStatus'],
data() {
return {
DictTypes,
projectStatus: '',
multipleStatus: [],
radioValue: '',
checkboxValues: []
}
},
mounted() {
// 监听字典数据加载完成事件
this.$on('dictReady', () => {
console.log('字典数据加载完成')
console.log('项目状态字典:', this.dict.projectStatus)
})
},
methods: {
// 获取字典标签
getDictLabel(name, value) {
return this.getDictLabel(name, value)
},
// 刷新项目状态字典
async refreshProjectStatus() {
try {
await this.refreshDict('projectStatus')
this.$message.success('项目状态字典刷新成功')
} catch (error) {
this.$message.error('项目状态字典刷新失败')
}
},
// 清除项目状态缓存
clearProjectStatus() {
this.clearDict('projectStatus')
this.$message.success('项目状态缓存清除成功')
},
// 清除所有缓存
clearAllDicts() {
this.clearAllDicts()
this.$message.success('所有字典缓存清除成功')
}
}
}
</script>
<style scoped>
.dict-example {
padding: 20px;
}
.section {
margin-bottom: 30px;
padding: 20px;
border: 1px solid #e8e8e8;
border-radius: 4px;
}
.section h3 {
margin-top: 0;
margin-bottom: 15px;
color: #1890ff;
}
.demo-item {
margin-bottom: 15px;
display: flex;
align-items: center;
gap: 10px;
}
.demo-item label {
min-width: 120px;
font-weight: bold;
}
.result {
margin-left: 10px;
color: #666;
font-style: italic;
}
pre {
background-color: #f5f5f5;
padding: 10px;
border-radius: 4px;
max-height: 200px;
overflow-y: auto;
font-size: 12px;
}
</style>
\ No newline at end of file
import Dict from "./Dict"
/**
* Vue字典插件
* 用于全局混入字典功能,让所有组件都能使用字典数据
*/
const install = function(Vue) {
Vue.mixin({
data() {
// 如果组件配置了dicts选项,则初始化字典数据结构
if (this.$options.dicts instanceof Array) {
const dict = {
dict: {},
dictLabel: {},
}
return {
dict
}
}
return {}
},
created() {
// 如果组件配置了dicts选项,则初始化字典数据
if (this.$options.dicts instanceof Array) {
// 创建Dict实例并初始化字典数据
new Dict(this.dict).init(this.$options.dicts, () => {
// 使用 $nextTick 确保 DOM 更新完成后,再触发 dictReady 事件
this.$nextTick(() => {
this.$emit('dictReady')
})
})
}
},
methods: {
/**
* 获取字典数据
* @param {string} name 字典类型名称
* @returns {Array} 字典数据数组
*/
getDict(name) {
if (this.dict && this.dict[name]) {
return this.dict[name]
}
return []
},
/**
* 获取字典标签
* @param {string} name 字典类型名称
* @param {string|number} value 字典值
* @returns {string} 字典标签
*/
getDictLabel(name, value) {
if (this.dict && this.dict.dictLabel && this.dict.dictLabel[name]) {
return this.dict.dictLabel[name][value] || ''
}
return ''
},
/**
* 刷新字典数据
* @param {string} name 字典类型名称
* @returns {Promise} 刷新结果
*/
async refreshDict(name) {
if (this.dict) {
const dictInstance = new Dict(this.dict)
return await dictInstance.refreshDict(name)
}
},
/**
* 批量刷新字典数据
* @param {Array} names 字典类型名称数组
* @returns {Promise} 刷新结果
*/
async refreshDicts(names) {
if (this.dict) {
const dictInstance = new Dict(this.dict)
return await dictInstance.refreshDicts(names)
}
},
/**
* 清除字典缓存
* @param {string} name 字典类型名称
*/
clearDict(name) {
if (this.dict) {
const dictInstance = new Dict(this.dict)
dictInstance.clearDict(name)
}
},
/**
* 清除所有字典缓存
*/
clearAllDicts() {
if (this.dict) {
const dictInstance = new Dict(this.dict)
dictInstance.clearAllDicts()
}
}
}
})
}
export default { install }
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment