This commit is contained in:
ln1778 2024-06-20 14:42:44 +08:00
parent fffccbb7be
commit f510fc328a
10 changed files with 490 additions and 3 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@ -427,4 +427,10 @@ export function batch_repair_ack(data) {
}) })
} }
export function getDicts(dictType) {
return request({
url: '/api/sysdict/get_dict',
method: 'post',
data: {dict_code:Array.isArray(dictType)?dictType:[dictType]}
})
}

208
dict/Dict.js Normal file
View File

@ -0,0 +1,208 @@
import Vue from 'vue'
import { mergeRecursive } from "./../utils/ruoyi";
import DictMeta from './DictMeta'
import DictData from './DictData'
import { getDicts as getDicts } from './../api/InventoryManagement';
const DEFAULT_DICT_OPTIONS = {
types: [],
}
/**
* @classdesc 字典
* @property {Object} label 标签对象内部属性名为字典类型名称
* @property {Object} dict 字段数组内部属性名为字典类型名称
* @property {Array.<DictMeta>} _dictMetas 字典元数据数组
*/
export default class Dict {
constructor() {
this.owner = null
this.label = {}
this.type = {}
this.raw={}
}
init(options) {
return new Promise((r)=>{
let params=Object.assign([],options);
if (options instanceof Array) {
options = { types: options }
}
const opts = mergeRecursive(DEFAULT_DICT_OPTIONS, options)
if (opts.types === undefined) {
r();
throw new Error('need dict types')
}
getRequest(params).then((res)=>{
if(res&&res.datas){
const response=res.datas;
sessionStorage.setItem("dictdata",JSON.stringify(response));
Object.keys(response).map((k,i)=>{
let dictMeta=DictMeta.parse(k)
const type = dictMeta.type
Vue.set(this.label, type, {})
Vue.set(this.type, type, [])
Vue.set(this.raw, type, [])
if (dictMeta.lazy) {
return
}
let dicts = dictMeta.responseConverter(response, dictMeta)
if (!(dicts instanceof Array)) {
console.error('the return of responseConverter must be Array.<DictData>')
dicts = []
} else if (dicts.filter(d => d instanceof DictData).length !== dicts.length) {
console.error('the type of elements in dicts must be DictData')
dicts = []
}
this.type[type].splice(0, Number.MAX_SAFE_INTEGER, ...dicts) ;
let newraw=[];
dicts.forEach(d => {
newraw.push(d.raw);
Vue.set(this.label[type], d.value, d.label);
});
Vue.set(this.raw, type, newraw);
if(Object.keys(response).length-1==i){
r();
}
});
}
});
});
}
getDict(name){
return new Promise((r)=>{
let options=Array.isArray(name)?name:[name];
let params=Object.assign([],options);
if (options instanceof Array) {
options = { types: options }
}
const opts = mergeRecursive(DEFAULT_DICT_OPTIONS, options)
if (opts.types === undefined) {
r();
throw new Error('need dict types')
}
getRequest(params).then((res)=>{
if(res&&res.datas){
const response=res.datas;
Object.keys(response).map((k,i)=>{
let dictMeta=DictMeta.parse(k)
const type = dictMeta.type
Vue.set(this.label, type, {})
Vue.set(this.type, type, [])
Vue.set(this.raw, type, [])
if (dictMeta.lazy) {
return
}
let dicts = dictMeta.responseConverter(response, dictMeta)
if (!(dicts instanceof Array)) {
console.error('the return of responseConverter must be Array.<DictData>')
dicts = []
} else if (dicts.filter(d => d instanceof DictData).length !== dicts.length) {
console.error('the type of elements in dicts must be DictData')
dicts = []
}
this.type[type].splice(0, Number.MAX_SAFE_INTEGER, ...dicts)
let newraw=[];
dicts.forEach(d => {
newraw.push(d.raw);
Vue.set(this.label[type], d.value, d.label)
});
Vue.set(this.raw, type, newraw);
if(Object.keys(response).length-1==i){
r(dicts);
}
});
}
});
});
}
doSession(response){
return new Promise((r)=>{
Object.keys(response).map((k,i)=>{
let dictMeta=DictMeta.parse(k)
const type = dictMeta.type
Vue.set(this.label, type, {})
Vue.set(this.type, type, [])
Vue.set(this.raw, type, [])
if (dictMeta.lazy) {
return
}
let dicts = dictMeta.responseConverter(response, dictMeta)
if (!(dicts instanceof Array)) {
console.error('the return of responseConverter must be Array.<DictData>')
dicts = []
} else if (dicts.filter(d => d instanceof DictData).length !== dicts.length) {
console.error('the type of elements in dicts must be DictData')
dicts = []
}
this.type[type].splice(0, Number.MAX_SAFE_INTEGER, ...dicts);
let newraw=[];
dicts.forEach(d => {
newraw.push(d.raw);
Vue.set(this.label[type], d.value, d.label);
});
Vue.set(this.raw, type, newraw);
if(Object.keys(response).length-1==i){
r();
}
});
});
}
/**
* 重新加载字典
* @param {String} type 字典类型
*/
reloadDict(type) {
const dictMeta = this._dictMetas.find(e => e.type === type)
if (dictMeta === undefined) {
return Promise.reject(`the dict meta of ${type} was not found`)
}
return loadDict(this, dictMeta)
}
}
function getRequest(options) {
return getDicts(options);
}
/**
* 加载字典
* @param {Dict} dict 字典
* @param {DictMeta} dictMeta 字典元数据
* @returns {Promise}
*/
function loadDict(dict, dictMeta) {
return dictMeta.request(dictMeta)
.then(response => {
const type = dictMeta.type
let dicts = dictMeta.responseConverter(response, dictMeta)
if (!(dicts instanceof Array)) {
console.error('the return of responseConverter must be Array.<DictData>')
dicts = []
} else if (dicts.filter(d => d instanceof DictData).length !== dicts.length) {
console.error('the type of elements in dicts must be DictData')
dicts = []
}
dict.type[type].splice(0, Number.MAX_SAFE_INTEGER, ...dicts)
dicts.forEach(d => {
Vue.set(dict.label[type], d.value, d.label)
})
return dicts
})
}

19
dict/DictConverter.js Normal file
View File

@ -0,0 +1,19 @@
import DictOptions from './DictOptions'
import DictData from './DictData'
export default function(dict, dictMeta) {
// console.log(dict,"dict", dictMeta,"dictMeta");
const label = determineDictField(dict, dictMeta.labelField, ...DictOptions.DEFAULT_LABEL_FIELDS)
const value = determineDictField(dict, dictMeta.valueField, ...DictOptions.DEFAULT_VALUE_FIELDS)
const type = determineDictField(dict, dictMeta.typeField, ...DictOptions.DEFAULT_TYPE_FIELDS)
return new DictData(dict[label], dict[value], dict,dict[type])
}
/**
* 确定字典字段
* @param {DictData} dict
* @param {...String} fields
*/
function determineDictField(dict, ...fields) {
return fields.find(f => Object.prototype.hasOwnProperty.call(dict, f))
}

14
dict/DictData.js Normal file
View File

@ -0,0 +1,14 @@
/**
* @classdesc 字典数据
* @property {String} label 标签
* @property {*} value 标签
* @property {Object} raw 原始数据
*/
export default class DictData {
constructor(label, value, raw,type) {
this.label = label
this.value = value
this.raw = raw
this.type=type
}
}

40
dict/DictMeta.js Normal file
View File

@ -0,0 +1,40 @@
import { mergeRecursive } from "./../utils/ruoyi";
import DictOptions from './DictOptions'
/**
* @classdesc 字典元数据
* @property {String} type 类型
* @property {Function} request 请求
* @property {String} label 标签字段
* @property {String} value 值字段
*/
export default class DictMeta {
constructor(options) {
this.type = options.type
this.request = options.request,
this.responseConverter = options.responseConverter
this.labelField = options.labelField
this.valueField = options.valueField
this.typeField = options.typeField
this.lazy = options.lazy === true
}
}
/**
* 解析字典元数据
* @param {Object} options
* @returns {DictMeta}
*/
DictMeta.parse= function(options) {
let opts = null
if (typeof options === 'string') {
opts = DictOptions.metas[options] || {}
opts.type = options
} else if (typeof options === 'object') {
opts = options
}
opts = mergeRecursive(DictOptions.metas['*'], opts)
return new DictMeta(opts)
}

53
dict/DictOptions.js Normal file
View File

@ -0,0 +1,53 @@
import { mergeRecursive } from "./../utils/ruoyi";
import dictConverter from './DictConverter'
export const options = {
metas: {
'*': {
/**
* 字典请求方法签名为function(dictMeta: DictMeta): Promise
*/
request: (dictMeta) => {
return Promise.resolve([])
},
/**
* 字典响应数据转换器方法签名为function(response: Object, dictMeta: DictMeta): DictData
*/
responseConverter,
labelField: 'label',
valueField: 'value',
typeField:'type',
},
},
/**
* 默认标签字段
*/
DEFAULT_LABEL_FIELDS: ['label', 'name', 'title'],
/**
* 默认值字段
*/
DEFAULT_VALUE_FIELDS: ['value', 'id', 'uid', 'key'],
DEFAULT_TYPE_FIELDS: ['type','key'],
}
/**
* 映射字典
* @param {Object} response 字典数据
* @param {DictMeta} dictMeta 字典元数据
* @returns {DictData}
*/
function responseConverter(response, dictMeta) {
const dicts = response.content instanceof Array ? response.content : response
if (dicts === undefined) {
console.warn(`no dict data of "${dictMeta.type}" found in the response`)
return []
}
return dicts[dictMeta.type].map(d => dictConverter(d, dictMeta))
}
export function mergeOptions(src) {
mergeRecursive(options, src)
}
export default options

123
dict/index.js Normal file
View File

@ -0,0 +1,123 @@
import Dict from './Dict'
import { mergeOptions } from './DictOptions'
export default function (Vue, options) {
mergeOptions(options)
Vue.mixin({
data() {
if (this.$options === undefined || this.$options.dicts === undefined || this.$options.dicts === null) {
return {}
}
const dict = new Dict()
dict.owner = this
return {
dict,
dictstatus: false,
requesttime:0,
}
},
created() {
if (!(this.dict instanceof Dict)) {
return
}
let dicttime=sessionStorage.getItem("dicttime");
if(dicttime&&new Date().getTime()-Number(dicttime)>1000*60*720){
options.onCreated && options.onCreated(this.dict)
this.dict.init(this.$options.dicts).then(() => {
this.dictstatus = true;
sessionStorage.setItem("dicttime",new Date().getTime());
options.onReady && options.onReady(this.dict)
this.$nextTick(() => {
this.$emit('dictReady', this.dict);
if (this.$options.methods && this.$options.methods.onDictReady instanceof Function) {
this.$options.methods.onDictReady.call(this, this.dict)
}
})
})
}
const dictdata = sessionStorage.getItem("dictdata");
if (dictdata) {
let sedata = JSON.parse(dictdata);
const find=this.$options.dicts.find((f)=>{
let findchild=Object.keys(sedata).find((h)=>h.indexOf(f)>-1);
return !findchild;
});
if(find){
options.onCreated && options.onCreated(this.dict)
this.dict.init(this.$options.dicts).then(() => {
this.dictstatus = true;
sessionStorage.setItem("dicttime",new Date().getTime());
options.onReady && options.onReady(this.dict)
this.$nextTick(() => {
this.$emit('dictReady', this.dict)
if (this.$options.methods && this.$options.methods.onDictReady instanceof Function) {
this.$options.methods.onDictReady.call(this, this.dict)
}
})
})
}else{
this.dict.doSession(sedata).then(() => {
this.dictstatus = true;
this.$nextTick(() => {
this.$emit('dictReady', this.dict)
})
});
}
} else {
options.onCreated && options.onCreated(this.dict)
this.dict.init(this.$options.dicts).then(() => {
this.dictstatus = true;
sessionStorage.setItem("dicttime",new Date().getTime());
options.onReady && options.onReady(this.dict)
this.$nextTick(() => {
this.$emit('dictReady', this.dict)
if (this.$options.methods && this.$options.methods.onDictReady instanceof Function) {
this.$options.methods.onDictReady.call(this, this.dict)
}
})
})
}
},
methods: {
formatDict(datas, othertype, type, startype) {
let newdatas = {};
if (this.isObject(datas)) {
newdatas = datas
} else if(this.$isArray(datas)){
newdatas = datas[0];
}else{
return '-';
}
if (!othertype || typeof (othertype) == "undefined") {
return '-'
}
let filters = null;
if (newdatas[type]) {
filters = newdatas[type].find((f) => f.value == othertype);
} else if (newdatas[startype + '_' + type]) {
filters = newdatas[startype + '_' + type].find((f) => f.value == othertype);
}
return filters&&filters.label || '-'
},
getDict(name) {
new Promise((r)=>{
this.dict = new Dict();
this.dict.owner = this;
this.dict.getDict(name).then(() => {
r(this.dict);
})
});
}
}
})
}

View File

@ -14,6 +14,9 @@ import Tablepagination from "./commontable/tablepagination.vue";
import Tabletabs from "./commontable/tabletabs.vue"; import Tabletabs from "./commontable/tabletabs.vue";
import Configuration from "./commontable/configuration/index.vue"; import Configuration from "./commontable/configuration/index.vue";
import commont from "./commont"; import commont from "./commont";
import DataDict from './dict'
//查询字典的方法(获取数据的接口)
import { getDicts as getDicts } from './api/InventoryManagement';
const componentarr = [ const componentarr = [
appTitle, appTitle,
@ -33,11 +36,30 @@ const componentarr = [
Configuration Configuration
]; ];
let dictapi=DataDict;
const setDicturl=(fn)=>{
dictapi=fn
}
const install = function (Vue) { const install = function (Vue) {
// 判断是否安装 // 判断是否安装
if (install.installed) return; if (install.installed) return;
install.installed = true; install.installed = true;
// 遍历并注册全局组件 // 遍历并注册全局组件
Vue.use(DataDict, {
//数据字典元信息
metas: {
//'*'表示这是一个通用配置,适用于所有数据字典
'*': {
//labelField 和 valueField 是用于指定数据字典项中标签和值的字段名
labelField: 'dictLabel',
valueField: 'dictValue',
//这个函数用来请求数据字典的数据,调用 getDicts() 函数,并使用传入的 dictMeta.type 来获取相应类型的数据字典
request(dictMeta) {
return dictapi(dictMeta.type).then(res => res.datas)
},
},
},
})
componentarr.forEach((component) => Vue.component(component.name, component)); componentarr.forEach((component) => Vue.component(component.name, component));
commont.forEach((f)=>Vue.prototype[Object.keys(f)[0]]=Object.values(f)[0]) commont.forEach((f)=>Vue.prototype[Object.keys(f)[0]]=Object.values(f)[0])
}; };
@ -47,7 +69,9 @@ if (typeof window !== "undefined" && window.Vue) {
install(window.Vue); install(window.Vue);
} }
export default { export default {
setDicturl:()=>{},
install, install,
...componentarr ...componentarr,
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "erp-element-ui", "name": "erp-element-ui",
"version": "1.0.32", "version": "1.0.36",
"description": "", "description": "",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {