Merge pull request #37 from aringlai/vue3

feat: 添加枚举字典插件
This commit is contained in:
harrywan 2021-01-28 14:11:45 +08:00 committed by GitHub
commit 286040d678
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 329 additions and 2 deletions

View File

@ -15,6 +15,7 @@ const headPkgs = [
"fes-plugin-layout",
"fes-plugin-icon",
"fes-plugin-locale",
"fes-plugin-enums",
"create-fes-app"
];
const tailPkgs = [];

View File

@ -0,0 +1,3 @@
export default {
disableTypeCheck: false,
};

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020-present webank
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,2 @@

View File

@ -0,0 +1,33 @@
{
"name": "@webank/fes-plugin-enums",
"version": "2.0.0-alpha.2",
"description": "@webank/fes-plugin-enums",
"main": "lib/index.js",
"files": [
"lib"
],
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/WeBankFinTech/fes.js.git",
"directory": "packages/fes-plugin-enums"
},
"keywords": [
"fes"
],
"author": "aringlai",
"license": "MIT",
"bugs": {
"url": "https://github.com/WeBankFinTech/fes.js/issues"
},
"homepage": "https://github.com/WeBankFinTech/fes.js#readme",
"publishConfig": {
"access": "public"
},
"peerDependencies": {
"@webank/fes": "^2.0.0-alpha.0",
"vue": "^3.0.4"
}
}

View File

@ -0,0 +1,48 @@
import { readFileSync } from 'fs';
import { join } from 'path';
const namespace = 'plugin-enums';
export default (api) => {
const {
utils: { Mustache }
} = api;
api.describe({
key: 'enums',
config: {
schema(joi) {
return joi.object();
},
onChange: api.ConfigChangeType.regenerateTmpFiles
}
});
const absoluteFilePath = join(namespace, 'core.js');
api.onGenerateFiles(() => {
// 文件写出
const enums = api.config.enums || {};
api.writeTmpFile({
path: absoluteFilePath,
content: Mustache.render(
readFileSync(join(__dirname, 'runtime/core.tpl'), 'utf-8'),
{
REPLACE_ENUMS: JSON.stringify(enums)
}
)
});
api.copyTmpFiles({
namespace,
path: join(__dirname, 'runtime'),
ignore: ['.tpl']
});
});
api.addPluginExports(() => [
{
specifiers: ['enums'],
source: absoluteFilePath
}
]);
};

View File

@ -0,0 +1,176 @@
import { readonly } from "vue"
// [[key, value]],默认配置格式
const _ENUMS = {{{REPLACE_ENUMS}}}
const ENUMS = {}
Object.keys(_ENUMS).forEach(key => {
ENUMS[key] = convert(key, _ENUMS[key])
})
/**
* 获取枚举键值如不传key则返回name的枚举数组
* @param {string} name 枚举名称
* @param {string} key 枚举键名称
* @param {{
* dir: string
* extend: Array<{
* key:string
* dir:string
* transfer: Function
* }>}} opt 配置项
*/
function get(name, key, opt = { dir: 'value', extend: []}) {
if (Object.prototype.toString.call(key) === '[object Object]') {
opt = key
key = ''
}
let list = ENUMS[name] || []
if (key) {
let res = list.filter(item => item.key === key)[0]
if (!res) return key
return readonly(parseValueDir(res.value, opt.dir) || key)
} else {
return readonly(format(list, opt.extend))
}
}
/**
* 移除枚举
* @param {string} name 枚举名称
*/
function remove(name) {
delete ENUMS[name]
}
/**
* 添加一个新的枚举,重复添加会覆盖
* @param {string} name 枚举名称
* @param {Array<Object|Array>} _enum 枚举数组,数组元素可以是数组或者对象
* @param {object} opt {keyName: 'key', valueName: ''} keyName: 指定枚举键名称取值属性 valueName 指定枚举键值取值属性
*/
function push(name, _enum, opt = { keyName: '', valueName: '' }) {
if (ENUMS[name]) {
console.warn(`enums warn: the ${name}'s enum already exists, cover!`)
}
ENUMS[name] = convert(name, _enum, opt)
return get(name)
}
/**
* 基于现有的枚举,连接上新的枚举后返回新的枚举
* @param {string} name 枚举名称
* @param {Array<any|Array>} _enum 枚举数组,数组元素可以是数组或者对象
* @param {{
* keyName: string,
* valueName: string,
* before: boolean,
* extend: Array<{
* key: string
* dir: string
* transfer: Function
* }>
* }} opt 配置项keyName: 指定枚举键名称取值属性 valueName 指定枚举键值取值属性 before: 是否添加在现有的之前
*/
function concat(name, _enum, opt = { keyName: '', valueName: '', before: false, extend: [] }) {
let list = ENUMS[name] || []
let partList = convert(name, _enum, opt) || []
if (opt.before) {
list = partList.concat(list)
} else {
list = list.concat(partList)
}
return readonly(format(list, extend))
}
/**
* 格式化枚举
* @param {Array} _enum 枚举数组
* @param {Array<{key:string, dir:string, transfer: Function}>} extend 格式化规则
*/
function format(_enum = [], extend = []) {
if (!extend || extend.length <= 0) return _enum;
return _enum.map(item => {
let _item = {...item}
extend.forEach(fItem => {
if (!fItem.key) return
if (typeof fItem.transfer === 'function') {
_item[fItem.key] = fItem.transfer(item)
} else {
_item[fItem.key] = parseValueDir(item.value, fItem.dir)
}
})
return _item
})
}
/**
* 根据dir解析value的属性值
* @param value
* @param dir
*/
function parseValueDir(value, dir='value') {
if (['object', 'function'].indexOf(typeof value) || !value || !dir) return value
if (dir.startsWith('[')) {
let key = dir.slice(1, dir.indexOf(']'))
return parseValueDir(value[key], dir.slice(dir.indexOf(']') + 1))
} else {
if (dir.startsWith('.')) {
dir = dir.slice(1)
}
let index = dir.indexOf('.')
let _index = dir.indexOf('[')
if (index === -1) index = dir.length
if (_index === -1) _index = dir.length
index = Math.min(index, _index)
let key = dir.slice(0, index)
return parseValueDir(value[key], dir.slice(index))
}
}
/**
* 转换传入的枚举数组
* @param {string} name 枚举名称
* @param {Array<Object|Array>} _enum 枚举数组,数组元素可以是数组或者对象
* @param {{keyName: 'key', valueName: string}} opt keyName: 指定枚举键名称取值属性 valueName 指定枚举键值取值属性
*/
function convert(name, _enum, opt = { keyName: '', valueName: '' }) {
if (!name) {
throw new Error(`enums error: name must not be empty`)
}
if (!Array.isArray(_enum)) {
throw new Error(`enums error: the ${name}'s enum must be array`)
}
let list = []
_enum.forEach((item, index) => {
let _item;
if (Array.isArray(item)) {
_item = {key: item[0], value: item[1]}
} else if(Object.prototype.toString.call(item) === '[object Object]') {
if (!opt.keyName) opt.keyName = 'key'
// key可能为空有场景需要使用比如全选
_item = {
key: item[opt.keyName],
value: opt.valueName ? item[opt.valueName] : item
}
} else {
console.warn(`enums warn: the key ${name} enum item[${index}] must be array or object`)
return
}
let res = list.filter(item => item.key === _item.key)[0]
if (res) { // key覆盖提示
console.warn(`enums warn: the key ${res.key} enum item already exists, cover!`)
res.value = _item.value
} else {
list.push(_item)
}
})
return list
}
export const enums = {
get,
push,
remove,
concat,
convert
}

View File

@ -26,5 +26,8 @@ export default {
},
devServer: {
port: 8080
},
enums: {
status: [['0', '无效的'], ['1', '有效的']]
}
};

View File

@ -48,6 +48,7 @@
"@webank/fes-plugin-layout": "^2.0.0-alpha.0",
"@webank/fes-plugin-locale": "^2.0.0-alpha.0",
"@webank/fes-plugin-model": "^2.0.0-alpha.0",
"@webank/fes-plugin-enums": "^2.0.0-alpha.0",
"ant-design-vue": "2.0.0-rc.3",
"vue": "3.0.4"
},

View File

@ -5,6 +5,10 @@
<access :id="accessId"> accessOnepicess1 <input /> </access>
<div v-access="accessId"> accessOnepicess2 <input /> </div>
<input />
<h4>数据字典</h4>
<div v-for="item in enumsGet('status')" :key="item.key">{{item.value}}{{item.key}}</div>
<div v-for="item in roles" :key="item.key">{{item.name}}{{item.disabled}}</div>
<div>{{enumsGet('roles', '2', { dir: 'eName' })}}</div>
</div>
</template>
<config>
@ -16,7 +20,7 @@
<script>
import { ref, onMounted } from 'vue';
import {
access, useAccess, useRouter, useI18n, locale
access, useAccess, useRouter, useI18n, locale, enums
} from '@webank/fes';
export default {
@ -26,6 +30,39 @@ export default {
const localI18n = useI18n();
const router = useRouter();
const accessId = ref('/onepiece1');
enums.push('roles', [
{
id: '1',
cName: '系统管理员',
eName: 'System',
perm: ['1', '2', '3']
},
{
id: '2',
cName: '业务管理员',
eName: 'Business',
perm: ['1', '2']
},
{
id: '3',
cName: '普通用户',
eName: 'User',
perm: ['1']
}
], { keyName: 'id' });
const roles = enums.get('roles', {
extend: [
{
key: 'name',
dir: 'cName'
},
{
key: 'disabled',
transfer: item => item.value.perm.some(i => i >= 2)
}
]
});
console.log(roles);
onMounted(() => {
console.log(router);
setTimeout(() => {
@ -43,7 +80,9 @@ export default {
accessId,
fes,
accessOnepicess,
t: localI18n.t
t: localI18n.t,
enumsGet: enums.get,
roles
};
}
};