diff --git a/.DS_Store b/.DS_Store index e35dec1..f0a2194 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/api/InventoryManagement.js b/api/InventoryManagement.js index 3b9fb68..5747b6a 100644 --- a/api/InventoryManagement.js +++ b/api/InventoryManagement.js @@ -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]} +}) +} \ No newline at end of file diff --git a/dict/Dict.js b/dict/Dict.js new file mode 100644 index 0000000..9554e90 --- /dev/null +++ b/dict/Dict.js @@ -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.} _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.') + 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.') + 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.') + 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.') + 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 + }) +} diff --git a/dict/DictConverter.js b/dict/DictConverter.js new file mode 100644 index 0000000..dd77e2b --- /dev/null +++ b/dict/DictConverter.js @@ -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)) +} diff --git a/dict/DictData.js b/dict/DictData.js new file mode 100644 index 0000000..63756bc --- /dev/null +++ b/dict/DictData.js @@ -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 + } +} diff --git a/dict/DictMeta.js b/dict/DictMeta.js new file mode 100644 index 0000000..ebca56a --- /dev/null +++ b/dict/DictMeta.js @@ -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) +} diff --git a/dict/DictOptions.js b/dict/DictOptions.js new file mode 100644 index 0000000..ebfd7cd --- /dev/null +++ b/dict/DictOptions.js @@ -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 diff --git a/dict/index.js b/dict/index.js new file mode 100644 index 0000000..54914ea --- /dev/null +++ b/dict/index.js @@ -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); + }) + }); + } + } + }) +} diff --git a/index.js b/index.js index 18b76e7..d839bdb 100644 --- a/index.js +++ b/index.js @@ -14,6 +14,9 @@ import Tablepagination from "./commontable/tablepagination.vue"; import Tabletabs from "./commontable/tabletabs.vue"; import Configuration from "./commontable/configuration/index.vue"; import commont from "./commont"; +import DataDict from './dict' +//查询字典的方法(获取数据的接口) +import { getDicts as getDicts } from './api/InventoryManagement'; const componentarr = [ appTitle, @@ -33,11 +36,30 @@ const componentarr = [ Configuration ]; +let dictapi=DataDict; +const setDicturl=(fn)=>{ + dictapi=fn +} const install = function (Vue) { // 判断是否安装 if (install.installed) return; 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)); 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); } export default { + setDicturl:()=>{}, install, - ...componentarr + ...componentarr, + } diff --git a/package.json b/package.json index cc6aeac..166249d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "erp-element-ui", - "version": "1.0.32", + "version": "1.0.36", "description": "", "main": "index.js", "scripts": {