From da55ee38c75efc97a52e58b05ea5382edaa2bf36 Mon Sep 17 00:00:00 2001 From: Hamm Date: Tue, 19 Nov 2024 14:02:21 +0800 Subject: [PATCH 01/27] =?UTF-8?q?feat(decorator):=20=E9=87=8D=E6=9E=84=20`?= =?UTF-8?q?AirModel`=20=E5=8F=8A=E7=9B=B8=E5=85=B3=E8=A3=85=E9=A5=B0?= =?UTF-8?q?=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 更新 `AirModel`基类,简化字段定义 - 重构 `Field`装饰器,支持更多配置项 - 移除 `Type`、`Default` 等冗余装饰器 - 移除 `EntityConfig` 接口,简化实体配置 - 调整 `FormField`、`SearchField`等装饰器以适应新结构 - 更新相关帮助类和接口定义 Signed-off-by: Hamm --- base/AirEntity.ts | 18 +- base/AirModel.ts | 100 +++++--- component/Desensitize.vue | 21 +- component/Table.vue | 28 +-- component/ToolBar.vue | 16 +- config/AirFieldConfig.ts | 4 +- decorator/Custom.ts | 270 --------------------- decorator/EntityConfig.ts | 28 --- decorator/Field.ts | 76 ++++++ decorator/FormField.ts | 10 +- decorator/Model.ts | 28 +++ decorator/SearchField.ts | 10 +- decorator/TableField.ts | 10 +- helper/AirDesensitize.ts | 2 +- helper/AirPermission.ts | 28 +-- interface/decorators/IEntityConfig.ts | 109 --------- interface/decorators/IField.ts | 19 ++ interface/decorators/IFieldConfig.ts | 46 ++-- interface/decorators/IFormFieldConfig.ts | 4 +- interface/decorators/IModelConfig.ts | 125 ++++++++++ interface/decorators/ISearchFieldConfig.ts | 4 +- interface/decorators/ITableFieldConfig.ts | 4 +- model/AirExportModel.ts | 7 +- model/AirPage.ts | 12 +- model/AirRequest.ts | 7 +- model/AirRequestPage.ts | 7 +- model/AirResponsePage.ts | 22 +- model/AirSort.ts | 5 +- model/entity/AirMenuEntity.ts | 15 +- websocket/AirWebSocketEvent.ts | 7 +- 30 files changed, 487 insertions(+), 555 deletions(-) delete mode 100644 decorator/Custom.ts delete mode 100644 decorator/EntityConfig.ts create mode 100644 decorator/Field.ts create mode 100644 decorator/Model.ts create mode 100644 interface/decorators/IField.ts create mode 100644 interface/decorators/IModelConfig.ts diff --git a/base/AirEntity.ts b/base/AirEntity.ts index 2aa13e9c..42f8fa17 100644 --- a/base/AirEntity.ts +++ b/base/AirEntity.ts @@ -1,8 +1,8 @@ -import { Dictionary, Field, Type } from '../decorator/Custom' import { AirModel } from './AirModel' import { Table } from '../decorator/TableField' import { AirDisableDictionary } from '../model/AirDisableDictionary' import { AirConstant } from '../config/AirConstant' +import { Field } from '../decorator/Field' /** * # 实体超类 @@ -12,14 +12,15 @@ export class AirEntity extends AirModel { /** * ## 主键 `ID` */ - @Type(Number) - @Field('ID') id!: number + @Field({ + label: 'ID', + type: Number, + }) + id!: number /** * ## 是否禁用 */ - @Type(Boolean) - @Dictionary(AirDisableDictionary) @Table({ showColor: true, width: 80, @@ -27,7 +28,12 @@ export class AirEntity extends AirModel { forceShow: true, removed: true, }) - @Field('禁用') isDisabled!: boolean + @Field({ + label: '是否禁用', + type: Boolean, + dictionary: AirDisableDictionary, + }) + isDisabled!: boolean /** * ## 实例化一个实体 diff --git a/base/AirModel.ts b/base/AirModel.ts index 69ba8af3..4fecc1e8 100644 --- a/base/AirModel.ts +++ b/base/AirModel.ts @@ -3,23 +3,15 @@ import { AirConstant } from '../config/AirConstant' import { AirFormFieldConfig } from '../config/AirFormFieldConfig' import { AirSearchFieldConfig } from '../config/AirSearchFieldConfig' import { AirTableFieldConfig } from '../config/AirTableFieldConfig' -import { - getAlias, - getDefault, - getFieldName, - getFieldPrefix, - getIsArray, - getModelName, - getNoPrefix, - getToJson, - getToModel, - getType, -} from '../decorator/Custom' +import { getModelConfig } from '../decorator/Model' import { getFormConfig, getFormConfigList } from '../decorator/FormField' +import { getFieldConfig, getToJson, getToModel } from '../decorator/Field' import { getSearchConfigList } from '../decorator/SearchField' import { getTableConfigList } from '../decorator/TableField' +import { IFieldConfig } from '../interface/decorators/IFieldConfig' import { IJson } from '../interface/IJson' import { ClassConstructor } from '../type/ClassConstructor' +import { IModelConfig } from '../interface/decorators/IModelConfig' /** * # 模型超类 @@ -63,19 +55,16 @@ export class AirModel { */ static parse(instance: T, json: IJson = {}): T { const fieldKeyList = Object.keys(instance) + const modelConfig = getModelConfig(instance) for (const fieldKey of fieldKeyList) { - const defaultValue = getDefault(instance, fieldKey) - const FieldTypeClass = getType(instance, fieldKey) - const fieldAliasName = getAlias(instance, fieldKey) + const props = getFieldConfig(instance, fieldKey) let fieldData = json[ - (!getNoPrefix(instance, fieldKey) - ? getFieldPrefix(instance) - : AirConstant.EMPTY_STRING - ) - + (fieldAliasName || fieldKey)] + (!props.ignorePrefix && modelConfig.fieldPrefix ? modelConfig.fieldPrefix : AirConstant.EMPTY_STRING) + + (props.alias || fieldKey)] + if (fieldData === undefined) { // 没有值尝试获取默认值 - fieldData = getDefault(instance, fieldKey) + fieldData = props.default } (instance as IJson)[fieldKey] = fieldData @@ -90,7 +79,8 @@ export class AirModel { continue } } - if (getIsArray(instance, fieldKey)) { + const FieldTypeClass = props.type + if (props.array) { // 是数组 循环转换 const fieldValueList: IJson[] = [] if (typeof fieldData === 'object' && Array.isArray(fieldData)) { @@ -104,9 +94,9 @@ export class AirModel { (instance as IJson)[fieldKey] = fieldValueList continue } - if (defaultValue !== undefined && (fieldData === undefined || fieldData === null || fieldData === AirConstant.EMPTY_STRING)) { + if (props.default !== undefined && (fieldData === undefined || fieldData === null || fieldData === AirConstant.EMPTY_STRING)) { // 如果有默认值 则先给上默认值 - (instance as IJson)[fieldKey] = defaultValue + (instance as IJson)[fieldKey] = props.default } if (!FieldTypeClass || fieldData === undefined || fieldData === null) { @@ -138,7 +128,8 @@ export class AirModel { // 最后删除无用的数据 for (const fieldKey of fieldKeyList) { - const fieldAliasName = getAlias(instance, fieldKey) + const props = getFieldConfig(instance, fieldKey) + const fieldAliasName = props.alias || fieldKey if (fieldAliasName === fieldKey) { continue } @@ -148,22 +139,36 @@ export class AirModel { } /** - * ## 获取类的可阅读名字 - * 可使用 `@Model` 装饰器修饰 如无修饰 则直接返回类名 + * ## 获取模型类配置项 */ - static getModelName(): string { + static getModelConfig(): M { return this.newInstance() - .getModelName() + .getModelConfig() + } + + /** + * ## 获取模型类的可阅读名字 + */ + static getModelName(): string { + return this.newInstance().getModelName() } /** * ## 获取属性的可阅读名字 - * 可使用 `@Field` 装饰器修饰 如无修饰 则直接返回属性名 * @param fieldKey 属性名 */ static getFieldName(fieldKey: string): string { + return this.newInstance().getFieldName(fieldKey) + } + + /** + * ## 获取属性的配置 + * @param fieldKey 属性名 + * @returns 配置对象 + */ + static getFieldConfig

(fieldKey: string): P { return this.newInstance() - .getFieldName(fieldKey) + .getFieldConfig

(fieldKey) } /** @@ -280,6 +285,7 @@ export class AirModel { */ toJson(): IJson { const fieldKeyList = Object.keys(this) + const modelConfig = getModelConfig(this) const json: IJson = {} for (const fieldKey of fieldKeyList) { const fieldData = (this as IJson)[fieldKey] @@ -287,10 +293,11 @@ export class AirModel { // 如果属性值为 null 或 undefined 则不转换到JSON continue } - let fieldAliasName = getAlias(this, fieldKey) || fieldKey - if (!getNoPrefix(this, fieldKey) && getFieldPrefix(this)) { + const fieldConfig = getFieldConfig(this, fieldKey) + let fieldAliasName = fieldConfig.alias || fieldKey + if (!fieldConfig.ignorePrefix && modelConfig.fieldPrefix) { // 按忽略前缀规则获取别名 - fieldAliasName = getFieldPrefix(this) + fieldAliasName + fieldAliasName = modelConfig.fieldPrefix + fieldAliasName } const toJsonFunction = getToJson(this, fieldKey) json[fieldAliasName || fieldKey] = fieldData @@ -328,13 +335,31 @@ export class AirModel { return json } + /** + * ## `请直接调用静态方法获取` + * ! 内部使用的保留方法 + * @deprecated + */ + getModelConfig(): M { + return getModelConfig(this) + } + /** * ## `请直接调用静态方法获取` * ! 内部使用的保留方法 * @deprecated */ getModelName(): string { - return getModelName(this) || this.constructor.name + return getModelConfig(this).label || this.constructor.name + } + + /** + * ## `请直接调用静态方法获取` + * ! 内部使用的保留方法 + * @deprecated + */ + getFieldConfig

(fieldKey: string): P { + return getFieldConfig

(this, fieldKey) } /** @@ -343,7 +368,7 @@ export class AirModel { * @deprecated */ getFieldName(fieldKey: string): string { - return getFieldName(this, fieldKey) + return getFieldConfig(this, fieldKey).label || fieldKey } /** @@ -361,7 +386,8 @@ export class AirModel { * @deprecated */ getFormFieldLabel(fieldKey: string): string { - return this.getCustomFormFieldConfig(fieldKey)?.label || this.getFieldName(fieldKey) + const props = getFieldConfig(this, fieldKey) + return this.getCustomFormFieldConfig(fieldKey)?.label || props.label || fieldKey } /** diff --git a/component/Desensitize.vue b/component/Desensitize.vue index 80f75484..08a22642 100644 --- a/component/Desensitize.vue +++ b/component/Desensitize.vue @@ -1,8 +1,8 @@ - + diff --git a/component/Table.vue b/component/Table.vue index 5a065e58..7db5135e 100644 --- a/component/Table.vue +++ b/component/Table.vue @@ -1104,7 +1104,7 @@ function getPayloadRowData(row: IJson, config: AirTableFieldConfig): AirAny { if (row[config.key] && row[config.key].length > 0) { // 对象数组挂载 return row[config.key].map((i: IJson) => i[config.payloadField || '']) - .join(config.arraySplitor) + .join(config.arraySeparator) } } return config.emptyValue @@ -1312,8 +1312,8 @@ watch( // 分页后滚动条置顶 const table = document.querySelector(`#${tableId}`) - const bodyWrapp = table?.querySelector('.el-scrollbar__wrap') as HTMLElement - bodyWrapp.scrollTop = 0 + const bodyWrap = table?.querySelector('.el-scrollbar__wrap') as HTMLElement + bodyWrap.scrollTop = 0 }) }, ) diff --git a/component/Upload.vue b/component/Upload.vue index 8d96b883..cc9b0679 100644 --- a/component/Upload.vue +++ b/component/Upload.vue @@ -1,7 +1,7 @@