feat: generate linkTo pair field

This commit is contained in:
chenos 2020-12-28 11:12:33 +08:00
parent 94c386e7aa
commit 976bc5d66e
6 changed files with 113 additions and 22 deletions

View File

@ -39,17 +39,17 @@ export default {
showInForm: true, showInForm: true,
}, },
}, },
{ // {
interface: 'linkTo', // interface: 'linkTo',
title: '书籍', // title: '书籍',
target: 'books', // target: 'books',
labelField: 'name', // labelField: 'name',
component: { // component: {
showInTable: true, // showInTable: true,
showInDetail: true, // showInDetail: true,
showInForm: true, // showInForm: true,
}, // },
}, // },
{ {
interface: 'createdBy', interface: 'createdBy',
title: '创建人', title: '创建人',

View File

@ -17,17 +17,17 @@ export default {
showInForm: true, showInForm: true,
}, },
}, },
{ // {
interface: 'linkTo', // interface: 'linkTo',
title: '作者', // title: '作者',
target: 'authors', // target: 'authors',
labelField: 'name', // labelField: 'name',
component: { // component: {
showInTable: true, // showInTable: true,
showInDetail: true, // showInDetail: true,
showInForm: true, // showInForm: true,
}, // },
}, // },
{ {
interface: 'createdBy', interface: 'createdBy',
title: '创建人', title: '创建人',

View File

@ -1,4 +1,5 @@
import FieldModel from '../models/field'; import FieldModel from '../models/field';
import { BELONGSTO, BELONGSTOMANY, HASMANY } from '@nocobase/database';
export default async function (model: FieldModel, options: any = {}) { export default async function (model: FieldModel, options: any = {}) {
const { migrate = true } = options; const { migrate = true } = options;
@ -16,4 +17,5 @@ export default async function (model: FieldModel, options: any = {}) {
if (migrate) { if (migrate) {
await model.migrate(options); await model.migrate(options);
} }
await model.generatePairField(options);
} }

View File

@ -5,4 +5,5 @@ export default async function (model: FieldModel, options: any = {}) {
if (migrate) { if (migrate) {
await model.migrate(options); await model.migrate(options);
} }
await model.generatePairField(options);
} }

View File

@ -331,6 +331,7 @@ export const linkTo = {
options: { options: {
interface: 'linkTo', interface: 'linkTo',
multiple: true, // 可能影响 type multiple: true, // 可能影响 type
paired: false,
type: 'belongsToMany', type: 'belongsToMany',
// name, // name,
// target: '关联表', // 用户会输入 // target: '关联表', // 用户会输入

View File

@ -6,6 +6,7 @@ import { merge } from '../utils';
import { BuildOptions } from 'sequelize'; import { BuildOptions } from 'sequelize';
import { SaveOptions, Utils } from 'sequelize'; import { SaveOptions, Utils } from 'sequelize';
import { generateCollectionName } from './collection'; import { generateCollectionName } from './collection';
import { BELONGSTO, BELONGSTOMANY, HASMANY } from '@nocobase/database';
interface FieldImportOptions extends SaveOptions { interface FieldImportOptions extends SaveOptions {
parentId?: number; parentId?: number;
@ -34,6 +35,7 @@ export class FieldModel extends BaseModel {
// 关系字段如果没有 name相关参数都随机生成 // 关系字段如果没有 name相关参数都随机生成
if (!data.name) { if (!data.name) {
data.name = generateFieldName(); data.name = generateFieldName();
data.paired = true;
// 通用,关系表 // 通用,关系表
if (!data.target) { if (!data.target) {
data.target = generateCollectionName(); data.target = generateCollectionName();
@ -75,6 +77,91 @@ export class FieldModel extends BaseModel {
this.set('name', generateFieldName()); this.set('name', generateFieldName());
} }
async generatePairField(options) {
const {interface: control, paired, type, target, sourceKey, targetKey, foreignKey, otherKey, through, collection_name} = this.get();
if (control !== 'linkTo' || type !== 'belongsToMany' || !collection_name || !paired) {
return;
}
if (!this.database.isDefined(target)) {
return;
}
const targetTable = this.database.getTable(target);
const Field = FieldModel;
let labelField = 'id';
const targetField = await Field.findOne({
...options,
where: {
type: 'string',
collection_name: target,
},
order: [['sort', 'asc']],
});
if (targetField) {
labelField = targetField.get('name');
}
const collection = await this.getCollection();
let targetOptions:any = {
...types.linkTo.options,
interface: 'linkTo',
title: collection.get('title'),
collection_name: target,
options: {
paired: true,
target: collection_name,
labelField,
},
component: {
showInTable: true,
showInForm: true,
showInDetail: true,
},
};
// 暂时不处理 hasone
switch (type) {
case 'hasMany':
targetOptions.type = 'belongsTo';
targetOptions.options.targetKey = sourceKey;
targetOptions.options.foreignKey = foreignKey;
break;
case 'belongsTo':
targetOptions.type = 'hasMany';
targetOptions.options.sourceKey = targetKey;
targetOptions.options.foreignKey = foreignKey;
break;
case 'belongsToMany':
targetOptions.type = 'belongsToMany';
targetOptions.options.sourceKey = targetKey;
targetOptions.options.foreignKey = otherKey;
targetOptions.options.targetKey = sourceKey;
targetOptions.options.otherKey = foreignKey;
targetOptions.options.through = through;
break;
}
const associations = targetTable.getAssociations();
// console.log(associations);
for (const association of associations.values()) {
if (association instanceof BELONGSTOMANY) {
if (
association.options.foreignKey === otherKey
&& association.options.sourceKey === targetKey
&& association.options.otherKey === foreignKey
&& association.options.targetKey === sourceKey
&& association.options.through === through
) {
return;
}
}
// if (association instanceof BELONGSTO) {
// continue;
// }
// if (association instanceof HASMANY) {
// continue;
// }
}
const f = await Field.create(targetOptions, options);
console.log({targetOptions}, f.get('options'));
}
setInterface(value) { setInterface(value) {
const { options } = types[value]; const { options } = types[value];
let args = []; let args = [];