diff --git a/packages/plugin-collections/src/__tests__/base-model.test.ts b/packages/plugin-collections/src/__tests__/base-model.test.ts index 86904f003..89242458e 100644 --- a/packages/plugin-collections/src/__tests__/base-model.test.ts +++ b/packages/plugin-collections/src/__tests__/base-model.test.ts @@ -17,6 +17,31 @@ describe('base model', () => { name: 'name', type: 'string', }, + { + name: 'title', + type: 'virtual', + }, + { + name: 'content', + type: 'virtual', + set(val) { + // 留空 + } + }, + { + name: 'key1', + type: 'virtual', + set(val) { + this.setDataValue('options.key1', `111${val}111`); + } + }, + { + name: 'key2', + type: 'virtual', + get() { + return 'val2'; + } + }, { type: 'json', name: 'component', @@ -143,4 +168,25 @@ describe('base model', () => { arr: [{a: 'a'}, {b: 'b'}], }); }); + + it.only('update virtual attribute', async () => { + await test.update({ + title: 'xxx', // 虚拟字段没 set 转存 options + content: 'content123', // set 留空,这个 key 什么也不做 + key1: 'val1', // 走 set 方法 + }); + // 重新获取再验证 + const test2 = await TestModel.findByPk(test.id); + expect(test2.get()).toMatchObject({ + abc: { aa: 'aa', bb: 'bb' }, + bcd: 'bbb', + name: '123', + component: { a: 'a', b: 'b' }, + arr: [{a: 'a'}, {b: 'b'}], + title: 'xxx', + key2: 'val2', // key2 为 get 方法取的 + key1: '111val1111', + }); + expect(test2.get('content')).toBeUndefined(); + }); }); diff --git a/packages/plugin-collections/src/collections/collections.ts b/packages/plugin-collections/src/collections/collections.ts index 15b27dcd7..0a46b1023 100644 --- a/packages/plugin-collections/src/collections/collections.ts +++ b/packages/plugin-collections/src/collections/collections.ts @@ -50,7 +50,7 @@ export default { { interface: 'string', type: 'virtual', - name: 'options.icon', + name: 'icon', title: '图标', component: { type: 'string', @@ -62,7 +62,7 @@ export default { { interface: 'radio', type: 'virtual', - name: 'options.defaultView', + name: 'defaultView', title: '默认视图', defaultValue: 'table', dataSource: [ @@ -80,7 +80,7 @@ export default { { interface: 'radio', type: 'virtual', - name: 'options.mode', + name: 'mode', title: '表格模式', defaultValue: 'default', dataSource: [ @@ -99,7 +99,7 @@ export default { { interface: 'radio', type: 'virtual', - name: 'options.defaultPerPage', + name: 'defaultPerPage', title: '每页显示几行数据', defaultValue: 50, dataSource: [ @@ -116,7 +116,7 @@ export default { { interface: 'boolean', type: 'virtual', - name: 'options.draggable', + name: 'draggable', title: '支持拖拽数据排序', showInForm: true, showInDetail: true, diff --git a/packages/plugin-collections/src/collections/fields.ts b/packages/plugin-collections/src/collections/fields.ts index 4d68921ab..c85318f5b 100644 --- a/packages/plugin-collections/src/collections/fields.ts +++ b/packages/plugin-collections/src/collections/fields.ts @@ -62,7 +62,7 @@ export default { { interface: 'subTable', type: 'virtual', - name: 'options.dataSource', + name: 'dataSource', title: '可选项', component: { type: 'table', diff --git a/packages/plugin-collections/src/collections/tabs.ts b/packages/plugin-collections/src/collections/tabs.ts index 4cae10ab8..e8a519622 100644 --- a/packages/plugin-collections/src/collections/tabs.ts +++ b/packages/plugin-collections/src/collections/tabs.ts @@ -63,7 +63,7 @@ export default { { interface: 'string', type: 'virtual', - name: 'options.association', + name: 'association', title: '相关数据表', component: { type: 'string', diff --git a/packages/plugin-collections/src/models/base.ts b/packages/plugin-collections/src/models/base.ts index c2dc8d8ad..caa35a1df 100644 --- a/packages/plugin-collections/src/models/base.ts +++ b/packages/plugin-collections/src/models/base.ts @@ -1,5 +1,5 @@ import _ from 'lodash'; -import { Model } from '@nocobase/database'; +import { getDataTypeKey, Model } from '@nocobase/database'; export class BaseModel extends Model { get additionalAttribute() { @@ -7,11 +7,28 @@ export class BaseModel extends Model { return _.get(tableOptions, 'additionalAttribute') || 'options'; } + hasGetAttribute(key: string) { + const attribute = this.rawAttributes[key]; + // virtual 如果有 get 方法就直接走 get + if (attribute && attribute.type && getDataTypeKey(attribute.type) === 'VIRTUAL') { + return !!attribute.get; + } + return !!attribute; + } + + hasSetAttribute(key: string) { + const attribute = this.rawAttributes[key]; + // virtual 如果有 set 方法就直接走 set + if (attribute && attribute.type && getDataTypeKey(attribute.type) === 'VIRTUAL') { + return !!attribute.set; + } + return !!attribute; + } + get(key?: any, options?: any) { if (typeof key === 'string') { const [column, ...path] = key.split('.'); - const attribute = this.rawAttributes[column]; - if (attribute) { + if (this.hasGetAttribute(column)) { const value = super.get(column, options); if (path.length) { return _.get(value, path); @@ -29,8 +46,7 @@ export class BaseModel extends Model { getDataValue(key: any) { const [column, ...path] = key.split('.'); - const attribute = this.rawAttributes[column]; - if (attribute) { + if (this.hasGetAttribute(column)) { const value = super.getDataValue(column); if (path.length) { return _.get(value, path); @@ -54,8 +70,7 @@ export class BaseModel extends Model { } const [column, ...path] = key.split('.'); this.changed(column, true); - const attribute = this.rawAttributes[column]; - if (attribute) { + if (this.hasSetAttribute(column)) { if (!path.length) { return super.set(key, value, options); } @@ -83,8 +98,7 @@ export class BaseModel extends Model { } const [column, ...path] = key.split('.'); this.changed(column, true); - const attribute = this.rawAttributes[column]; - if (attribute) { + if (this.hasSetAttribute(column)) { if (!path.length) { return super.setDataValue(key, value); }