fix: change the field options merge strategy

This commit is contained in:
chenos 2020-12-09 20:45:15 +08:00
parent 96510cc929
commit 13385b8ab3
7 changed files with 100 additions and 12 deletions

View File

@ -256,4 +256,31 @@ describe('models.base', () => {
name: 'name1', name: 'name1',
}); });
}); });
it('component', async () => {
const t = await TestModel.create({
component: {
arr: [
{a: 'a', aa: 'aa'},
{b: 'b', bb: 'bb'},
{c: 'c', cc: 'cc'},
],
},
});
t.set({
component: {
arr: [
{a: 'aa'},
{b: 'bb'},
],
}
});
await t.save();
expect(t.get('component')).toEqual({
arr: [
{a: 'aa'},
{b: 'bb'},
],
});
})
}); });

View File

@ -1,6 +1,6 @@
import { Agent, getAgent, getApp } from '../'; import { Agent, getAgent, getApp } from '../';
import { Application } from '@nocobase/server'; import { Application } from '@nocobase/server';
import * as types from '../../interfaces/types'; import { options, types } from '../../interfaces';
jest.setTimeout(30000); jest.setTimeout(30000);
import { FieldModel } from '../../models'; import { FieldModel } from '../../models';
describe('models.field', () => { describe('models.field', () => {
@ -20,4 +20,34 @@ describe('models.field', () => {
field.setInterface('updatedAt'); field.setInterface('updatedAt');
expect(field.get()).toMatchObject(types.updatedAt.options) expect(field.get()).toMatchObject(types.updatedAt.options)
}); });
it('dataSource', async () => {
const Collection = app.database.getModel('collections');
// @ts-ignore
const collection = await Collection.create({
title: 'tests',
});
await collection.updateAssociations({
fields: [
{
title: 'xx',
name: 'xx',
interface: 'select',
type: 'virtual',
dataSource: [
{label: 'xx', value: 'xx'},
],
component: {
type: 'string',
showInDetail: true,
showInForm: true,
},
}
],
});
const fields = await collection.getFields();
expect(fields[0].get('dataSource')).toEqual([
{label: 'xx', value: 'xx'},
]);
});
}); });

View File

@ -3,9 +3,9 @@ import * as types from '../interfaces/types';
import _ from 'lodash'; import _ from 'lodash';
export default async function (model: FieldModel) { export default async function (model: FieldModel) {
if (model.get('interface')) { // if (model.get('interface')) {
model.setInterface(model.get('interface')); // model.setInterface(model.get('interface'));
} // }
// 生成随机 name 要放最后 // 生成随机 name 要放最后
model.generateNameIfNull(); model.generateNameIfNull();
} }

View File

@ -208,7 +208,8 @@ export const datetime = {
showTime: false, showTime: false,
filterable: true, filterable: true,
sortable: true, sortable: true,
format: 'YYYY-MM-DD HH:mm:ss', dateFormat: 'YYYY-MM-DD',
timeFormat: 'HH:mm:ss',
component: { component: {
type: 'date', type: 'date',
}, },
@ -222,7 +223,7 @@ export const time = {
type: 'time', type: 'time',
filterable: true, filterable: true,
sortable: true, sortable: true,
format: 'HH:mm:ss', timeFormat: 'HH:mm:ss',
component: { component: {
type: 'time', type: 'time',
}, },
@ -271,7 +272,7 @@ export const subTable = {
type: 'hasMany', type: 'hasMany',
// fields: [], // fields: [],
component: { component: {
type: 'subTable', type: 'table',
}, },
}, },
}; };
@ -351,6 +352,8 @@ export const createdAt = {
type: 'date', type: 'date',
name: 'created_at', name: 'created_at',
showTime: true, showTime: true,
dateFormat: 'YYYY-MM-DD',
timeFormat: 'HH:mm:ss',
required: true, required: true,
filterable: true, filterable: true,
sortable: true, sortable: true,
@ -373,12 +376,14 @@ export const updatedBy = {
}; };
export const updatedAt = { export const updatedAt = {
title: '更新日期', title: '更新时间',
options: { options: {
interface: 'updatedAt', interface: 'updatedAt',
type: 'date', type: 'date',
name: 'updated_at', name: 'updated_at',
showTime: true, showTime: true,
dateFormat: 'YYYY-MM-DD',
timeFormat: 'HH:mm:ss',
required: true, required: true,
filterable: true, filterable: true,
sortable: true, sortable: true,

View File

@ -1,6 +1,6 @@
import _ from 'lodash'; import _ from 'lodash';
import { getDataTypeKey, Model } from '@nocobase/database'; import { getDataTypeKey, Model } from '@nocobase/database';
import { Utils } from 'sequelize'; import { merge } from '../utils';
export function generateName(title?: string): string { export function generateName(title?: string): string {
return `${Math.random().toString(36).replace('0.', '').slice(-4).padStart(4, '0')}`; return `${Math.random().toString(36).replace('0.', '').slice(-4).padStart(4, '0')}`;
@ -83,7 +83,7 @@ export class BaseModel extends Model {
// 如果是 object 数据merge 处理 // 如果是 object 数据merge 处理
if (_.isPlainObject(value)) { if (_.isPlainObject(value)) {
// @ts-ignore // @ts-ignore
value = Utils.merge(this.get(key)||{}, value); value = merge(this.get(key)||{}, value);
} }
const [column, ...path] = key.split('.'); const [column, ...path] = key.split('.');
if (!options.raw) { if (!options.raw) {

View File

@ -2,7 +2,8 @@ import _ from 'lodash';
import BaseModel from './base'; import BaseModel from './base';
import { FieldOptions } from '@nocobase/database'; import { FieldOptions } from '@nocobase/database';
import * as types from '../interfaces/types'; import * as types from '../interfaces/types';
import { Utils } from 'sequelize'; import { merge } from '../utils';
import { BuildOptions } from 'sequelize';
export function generateFieldName(title?: string): string { export function generateFieldName(title?: string): string {
return `f_${Math.random().toString(36).replace('0.', '').slice(-4).padStart(4, '0')}`; return `f_${Math.random().toString(36).replace('0.', '').slice(-4).padStart(4, '0')}`;
@ -10,6 +11,22 @@ export function generateFieldName(title?: string): string {
export class FieldModel extends BaseModel { export class FieldModel extends BaseModel {
constructor(values: any = {}, options: any = {}) {
let data = {
...(values.options||{}),
..._.omit(values, 'options'),
};
const interfaceType = data.interface;
if (interfaceType) {
const { options } = types[interfaceType];
let args = [options, data];
// @ts-ignore
data = merge(...args);
}
// @ts-ignore
super(data, options);
}
generateName() { generateName() {
this.set('name', generateFieldName()); this.set('name', generateFieldName());
} }
@ -31,7 +48,7 @@ export class FieldModel extends BaseModel {
args = [options, this.get()]; args = [options, this.get()];
} }
// @ts-ignore // @ts-ignore
const values = Utils.merge(...args); const values = merge(...args);
this.set(values); this.set(values);
} }

View File

@ -0,0 +1,9 @@
import deepmerge from 'deepmerge';
const overwriteMerge = (destinationArray, sourceArray, options) => sourceArray
export function merge(obj1: any, obj2: any) {
return deepmerge(obj1, obj2, {
arrayMerge: overwriteMerge,
});
}