diff --git a/packages/app/src/api/collections/authors.ts b/packages/app/src/api/collections/authors.ts index a25486102..cfb41205d 100644 --- a/packages/app/src/api/collections/authors.ts +++ b/packages/app/src/api/collections/authors.ts @@ -39,17 +39,17 @@ export default { showInForm: true, }, }, - { - interface: 'linkTo', - title: '书籍', - target: 'books', - labelField: 'name', - component: { - showInTable: true, - showInDetail: true, - showInForm: true, - }, - }, + // { + // interface: 'linkTo', + // title: '书籍', + // target: 'books', + // labelField: 'name', + // component: { + // showInTable: true, + // showInDetail: true, + // showInForm: true, + // }, + // }, { interface: 'createdBy', title: '创建人', diff --git a/packages/app/src/api/collections/books.ts b/packages/app/src/api/collections/books.ts index 6f786146c..4fe96f131 100644 --- a/packages/app/src/api/collections/books.ts +++ b/packages/app/src/api/collections/books.ts @@ -17,17 +17,17 @@ export default { showInForm: true, }, }, - { - interface: 'linkTo', - title: '作者', - target: 'authors', - labelField: 'name', - component: { - showInTable: true, - showInDetail: true, - showInForm: true, - }, - }, + // { + // interface: 'linkTo', + // title: '作者', + // target: 'authors', + // labelField: 'name', + // component: { + // showInTable: true, + // showInDetail: true, + // showInForm: true, + // }, + // }, { interface: 'createdBy', title: '创建人', diff --git a/packages/plugin-collections/src/hooks/fields-after-create.ts b/packages/plugin-collections/src/hooks/fields-after-create.ts index 6267766bb..715917a2a 100644 --- a/packages/plugin-collections/src/hooks/fields-after-create.ts +++ b/packages/plugin-collections/src/hooks/fields-after-create.ts @@ -1,4 +1,5 @@ import FieldModel from '../models/field'; +import { BELONGSTO, BELONGSTOMANY, HASMANY } from '@nocobase/database'; export default async function (model: FieldModel, options: any = {}) { const { migrate = true } = options; @@ -16,4 +17,5 @@ export default async function (model: FieldModel, options: any = {}) { if (migrate) { await model.migrate(options); } + await model.generatePairField(options); } diff --git a/packages/plugin-collections/src/hooks/fields-after-update.ts b/packages/plugin-collections/src/hooks/fields-after-update.ts index 9c4dfb44f..b5c44eb64 100644 --- a/packages/plugin-collections/src/hooks/fields-after-update.ts +++ b/packages/plugin-collections/src/hooks/fields-after-update.ts @@ -5,4 +5,5 @@ export default async function (model: FieldModel, options: any = {}) { if (migrate) { await model.migrate(options); } + await model.generatePairField(options); } diff --git a/packages/plugin-collections/src/interfaces/types.ts b/packages/plugin-collections/src/interfaces/types.ts index c7aa2391e..1ca62af38 100644 --- a/packages/plugin-collections/src/interfaces/types.ts +++ b/packages/plugin-collections/src/interfaces/types.ts @@ -331,6 +331,7 @@ export const linkTo = { options: { interface: 'linkTo', multiple: true, // 可能影响 type + paired: false, type: 'belongsToMany', // name, // target: '关联表', // 用户会输入 diff --git a/packages/plugin-collections/src/models/field.ts b/packages/plugin-collections/src/models/field.ts index ddff5359d..6c9ef4f78 100644 --- a/packages/plugin-collections/src/models/field.ts +++ b/packages/plugin-collections/src/models/field.ts @@ -6,6 +6,7 @@ import { merge } from '../utils'; import { BuildOptions } from 'sequelize'; import { SaveOptions, Utils } from 'sequelize'; import { generateCollectionName } from './collection'; +import { BELONGSTO, BELONGSTOMANY, HASMANY } from '@nocobase/database'; interface FieldImportOptions extends SaveOptions { parentId?: number; @@ -34,6 +35,7 @@ export class FieldModel extends BaseModel { // 关系字段如果没有 name,相关参数都随机生成 if (!data.name) { data.name = generateFieldName(); + data.paired = true; // 通用,关系表 if (!data.target) { data.target = generateCollectionName(); @@ -75,6 +77,91 @@ export class FieldModel extends BaseModel { 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) { const { options } = types[value]; let args = [];