oak-frontend-base/es/utils/usefulFn.js

332 lines
10 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { assert } from 'oak-domain/lib/utils/assert';
import { judgeRelation } from 'oak-domain/lib/store/relation';
import { get } from 'oak-domain/lib/utils/lodash';
import dayjs from 'dayjs';
import { ThousandCont, ToYuan } from 'oak-domain/lib/utils/money';
const tableWidthMap = {
1: 120,
2: 200,
3: 300,
4: 400,
};
export function getAttributes(attributes) {
return Object.assign({}, attributes, {
id: {
type: 'char',
params: {
length: 36,
},
},
$$createAt$$: {
type: 'datetime',
},
$$updateAt$$: {
type: 'datetime',
},
$$deleteAt$$: {
type: 'datetime',
},
$$seq$$: {
type: 'varchar',
},
});
}
export function resolvePath(dataSchema, entity, path) {
assert(!path.includes('['), '数组索引不需要携带[],请使用arr.0.value');
const attrs = path.split('.');
let idx = 0;
let _entity = entity;
let attr = path;
let attrType = undefined;
let attribute = undefined;
while (idx <= attrs.length - 1) {
attr = attrs[idx];
if (!isNaN(parseInt(attr))) {
idx++;
continue;
}
const relation = judgeRelation(dataSchema, _entity, attr, true);
if (relation === 1) {
const attributes = getAttributes(dataSchema[_entity].attributes);
attribute = attributes[attr];
attrType = attribute.type;
if (attr === 'id') {
attrType = 'ref';
}
else {
if (attrType === 'ref') {
attr = attribute.ref;
}
}
}
else if (relation === 2) {
// entity entityId
_entity = attr;
}
else if (typeof relation === 'string') {
_entity = relation;
}
else if (relation instanceof Array) {
_entity = relation[0];
}
else {
assert(relation === -1);
}
idx++;
}
return {
entity: _entity,
attr,
attrType,
attribute,
};
}
// 强制类型
export function isAttributeType(attribute) {
return attribute;
}
export function getLinkUrl(attribute, props) {
if (typeof attribute === 'string') {
return '';
}
let href = attribute.linkUrl || '';
const searchParams = [];
Object.keys(props).forEach((ele) => {
searchParams.push(`${ele}=${props[ele]}`);
});
if (!href.includes('?')) {
href += '?';
}
href += searchParams.join('&');
return href;
}
// 以下几个get方法只需要两个参数attribute和一个解析path对象只是后者类型还没定义
export function getPath(attribute) {
if (typeof attribute === 'string') {
return attribute;
}
return attribute.path;
}
export function getLabel(attribute, entity, attr, t) {
if (isAttributeType(attribute).label) {
return isAttributeType(attribute).label;
}
if (attr === '$$createAt$$' ||
attr === '$$updateAt$$' ||
attr === '$$deleteAt$$' ||
attr === '$$seq$$') {
return t(`common::${attr}`, {
'#oakModule': 'oak-frontend-base',
});
}
if (attr === 'id') {
return 'id';
}
return t(`${entity}:attr.${attr}`, {});
}
// 目前width属性可以是undefined只有特殊type或用户自定义才有值这样其余attr属性可以自适应
export function getWidth(attribute, attrType) {
let width;
if (isAttributeType(attribute).width) {
width = isAttributeType(attribute).width;
return width;
}
if (attrType === 'enum') {
width = 120;
}
if (isAttributeType(attribute).span) {
width = tableWidthMap[isAttributeType(attribute).span];
}
return width;
}
export function getValue(data, path, entity, attr, attrType, t) {
let value = get(data, path);
// 枚举类型还要通过i18转一下中文
if (attrType === 'enum' && value) {
value = t(`${entity}:v.${attr}.${value}`, {});
}
// 如果是dateTime
if (attrType === 'datetime' && value) {
value = dayjs(value).format('YYYY-MM-DD HH:mm');
}
if (attrType === 'boolean' && typeof value === 'boolean') {
value = t(`common::${String(value)}`, {
'#oakModule': 'oak-frontend-base',
});
}
if (attrType === 'money' && typeof value === 'number') {
value = t('common::money', {
value: ThousandCont(ToYuan(value)),
'#oakModule': 'oak-frontend-base'
});
}
return value;
}
export function getAlign(attribute) {
return isAttributeType(attribute).align || 'left';
}
export function getFixed(attribute) {
return isAttributeType(attribute).fixed;
}
export function getType(attribute, attrType) {
let type = attrType;
if (isAttributeType(attribute).type) {
type = isAttributeType(attribute).type;
}
return type;
}
function getLabelI18(dataSchema, entity, path, t) {
const { attr, entity: entityI8n } = resolvePath(dataSchema, entity, path);
return t(`${entityI8n}:attr.${attr}`, {});
}
export function makeDataTransformer(dataSchema, entity, attrDefs, t) {
const transformerFixedPart = attrDefs.map((ele) => {
if (typeof ele === 'string') {
const path = ele;
const { attrType, attr, entity: entityI8n, } = resolvePath(dataSchema, entity, path);
const label = getLabel(ele, entityI8n, attr, t);
const type = attrType;
return {
path,
label,
type,
attr,
};
}
else {
const { path, label, width, type } = ele;
return {
path,
label,
width,
type: type || 'varchar',
};
}
});
return (data) => transformerFixedPart.map((ele) => {
const { path } = ele;
const value = get(data, path);
return {
value,
...ele,
};
});
}
export function analyzeDataUpsertTransformer(dataSchema, entity, attrUpsertDefs) {
let geoDef = undefined;
const makeNativeFixedPart = (attr, def) => {
const attrDef = dataSchema[entity].attributes[attr]; // upsert应该不会涉及createAt这些内置属性
const { type, notNull: required, default: defaultValue, enumeration, params, } = attrDef;
assert(type !== 'ref');
return {
attr,
type: type,
required,
defaultValue: def?.hasOwnProperty('defaultValue')
? def.defaultValue
: defaultValue,
enumeration: enumeration?.map((ele) => ({
value: ele,
label: `${entity}:v.${attr}.${ele}`,
})),
min: typeof def?.min === 'number' ? def.min : params?.min,
max: typeof def?.max === 'number' ? def.max : params?.max,
maxLength: typeof def?.maxLength === 'number'
? def.maxLength
: params?.length,
get: (data) => data && data[attr],
};
};
const transformerFixedPart = attrUpsertDefs
.map((ele) => {
if (typeof ele === 'string') {
const rel = judgeRelation(dataSchema, entity, ele);
assert(rel === 1);
return makeNativeFixedPart(ele);
}
else if (typeof ele === 'object' && ele.type === 'geo') {
assert(!geoDef, '只能定义一个geo渲染对象');
geoDef = ele;
}
else {
const { attr, ...rest } = ele;
const rel = judgeRelation(dataSchema, entity, attr);
if (rel === 1) {
const fixedPart = makeNativeFixedPart(attr, ele);
return Object.assign(fixedPart, {
...rest,
});
}
const origAttr = rel === 2 ? 'entityId' : `${attr}Id`;
return {
required: !!dataSchema[entity].attributes[origAttr].notNull,
...rest,
get: (data) => data && data[origAttr],
attr: origAttr,
};
}
})
.filter((ele) => !!ele);
if (geoDef) {
// 暂时只放出poiName和coordinate
const { type, attributes, ...rest } = geoDef;
let attr = attributes?.coordinate || 'coordinate';
transformerFixedPart.push(Object.assign(makeNativeFixedPart(attr), {
type: 'coordinate',
extra: attributes,
}));
attr = attributes?.poiName || 'poiName';
transformerFixedPart.push(Object.assign(makeNativeFixedPart(attr), {
type: 'poiName',
...rest,
}));
}
return (data) => transformerFixedPart.map((ele) => {
const { get } = ele;
const value = get(data);
return {
value,
...ele,
};
});
}
export function translateAttributes(dataSchema, entity, attributes) {
const judgeAttributes = attributes.map((ele) => {
const path = getPath(ele);
const { attrType, attr, entity: entityI8n, } = resolvePath(dataSchema, entity, path);
return {
path,
attrType,
attr,
attribute: ele,
entity: entityI8n,
render: typeof ele === 'object' ? ele.render : undefined,
};
});
return judgeAttributes;
}
export function analyzeAttrMobileForCard(dataSchema, entity, t, attributes) {
return (data) => {
// 遍历用户传入的数据源
const coverData = data.map((row) => {
const rows = attributes.map((attribute) => {
const path = getPath(attribute);
const { attrType, attr, entity: entityI8n, } = resolvePath(dataSchema, entity, path);
const label = getLabel(attribute, entityI8n, attr, t);
const value = getValue(row, path, entityI8n, attr, attrType, t);
const type = getType(attribute, attrType);
return {
label,
value,
type,
};
});
return {
data: rows,
record: row,
};
});
return coverData;
};
}