feat: divide the fields into general and system
This commit is contained in:
parent
2f880c6cd0
commit
c34d82d180
@ -45,7 +45,7 @@ export default () => {
|
||||
'x-component': 'Input',
|
||||
'x-read-pretty': true,
|
||||
},
|
||||
fields: {
|
||||
generalFields: {
|
||||
type: 'array',
|
||||
title: '数据表字段',
|
||||
'x-decorator': 'FormItem',
|
||||
|
@ -23,7 +23,7 @@ export function useCollection(props: CollectionProviderProps) {
|
||||
collection = collections.find((item) => item.name === collectionName);
|
||||
}
|
||||
if (collection) {
|
||||
fields = collection?.fields || [];
|
||||
fields = collection?.generalFields || [];
|
||||
}
|
||||
let sortableField = collection?.sortable;
|
||||
if (collection?.sortable && typeof collection?.sortable === 'object') {
|
||||
|
@ -24,7 +24,8 @@ import {
|
||||
Input,
|
||||
Badge,
|
||||
message,
|
||||
Spin,
|
||||
Drawer,
|
||||
Space,
|
||||
} from 'antd';
|
||||
import { options, interfaces, getDefaultFields } from './interfaces';
|
||||
import {
|
||||
@ -127,11 +128,12 @@ export const DatabaseCollection = observer((props) => {
|
||||
>
|
||||
<DatabaseOutlined />
|
||||
</Button>
|
||||
<Modal
|
||||
bodyStyle={{
|
||||
overflow: 'auto',
|
||||
maxHeight: 'calc(100vh - 300px)',
|
||||
}}
|
||||
<Drawer
|
||||
width={'50%'}
|
||||
// bodyStyle={{
|
||||
// overflow: 'auto',
|
||||
// maxHeight: 'calc(100vh - 300px)',
|
||||
// }}
|
||||
title={
|
||||
<div style={{ textAlign: 'center' }}>
|
||||
<DndContext
|
||||
@ -249,21 +251,49 @@ export const DatabaseCollection = observer((props) => {
|
||||
</div>
|
||||
}
|
||||
visible={visible}
|
||||
onCancel={() => {
|
||||
onClose={() => {
|
||||
setVisible(false);
|
||||
}}
|
||||
okText={'保存'}
|
||||
cancelText={'关闭'}
|
||||
onOk={async () => {
|
||||
try {
|
||||
form.clearErrors();
|
||||
await form.validate(`${field.address.entire}.${activeIndex}.*`);
|
||||
delete field.value[activeIndex]['unsaved'];
|
||||
await createOrUpdateCollection(field.value[activeIndex]);
|
||||
await refresh();
|
||||
message.success('保存成功');
|
||||
} catch (error) {}
|
||||
}}
|
||||
footer={
|
||||
<Space>
|
||||
<Button
|
||||
onClick={() => {
|
||||
setVisible(false);
|
||||
}}
|
||||
>
|
||||
关闭
|
||||
</Button>
|
||||
<Button
|
||||
type={'primary'}
|
||||
onClick={async () => {
|
||||
try {
|
||||
form.clearErrors();
|
||||
await form.validate(
|
||||
`${field.address.entire}.${activeIndex}.*`,
|
||||
);
|
||||
delete field.value[activeIndex]['unsaved'];
|
||||
await createOrUpdateCollection(field.value[activeIndex]);
|
||||
await refresh();
|
||||
message.success('保存成功');
|
||||
} catch (error) {}
|
||||
}}
|
||||
>
|
||||
保存
|
||||
</Button>
|
||||
</Space>
|
||||
}
|
||||
// okText={'保存'}
|
||||
// cancelText={'关闭'}
|
||||
// onOk={async () => {
|
||||
// try {
|
||||
// form.clearErrors();
|
||||
// await form.validate(`${field.address.entire}.${activeIndex}.*`);
|
||||
// delete field.value[activeIndex]['unsaved'];
|
||||
// await createOrUpdateCollection(field.value[activeIndex]);
|
||||
// await refresh();
|
||||
// message.success('保存成功');
|
||||
// } catch (error) {}
|
||||
// }}
|
||||
>
|
||||
<FormLayout layout={'vertical'}>
|
||||
<RecursionField
|
||||
@ -279,7 +309,7 @@ export const DatabaseCollection = observer((props) => {
|
||||
{(form) => <pre>{JSON.stringify(form.values, null, 2)}</pre>}
|
||||
</FormConsumer> */}
|
||||
</FormLayout>
|
||||
</Modal>
|
||||
</Drawer>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
@ -3,65 +3,27 @@ import { TableOptions } from '@nocobase/database';
|
||||
export default {
|
||||
name: 'action_changes',
|
||||
title: '变动值',
|
||||
developerMode: true,
|
||||
internal: true,
|
||||
createdBy: false,
|
||||
updatedBy: false,
|
||||
createdAt: false,
|
||||
updatedAt: false,
|
||||
logging: false,
|
||||
fields: [
|
||||
{
|
||||
interface: 'linkTo',
|
||||
type: 'belongsTo',
|
||||
name: 'log',
|
||||
target: 'action_logs',
|
||||
title: '所属操作'
|
||||
},
|
||||
{
|
||||
type: 'jsonb',
|
||||
name: 'field',
|
||||
title: '字段信息',
|
||||
component: {
|
||||
type: 'logs.field',
|
||||
showInTable: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'jsonb',
|
||||
name: 'before',
|
||||
title: '操作前',
|
||||
component: {
|
||||
type: 'logs.fieldValue',
|
||||
showInTable: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'jsonb',
|
||||
name: 'after',
|
||||
title: '操作后',
|
||||
component: {
|
||||
type: 'logs.fieldValue',
|
||||
showInTable: true,
|
||||
},
|
||||
}
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
type: 'list',
|
||||
name: 'list',
|
||||
title: '查看'
|
||||
}
|
||||
],
|
||||
views_v2: [
|
||||
{
|
||||
type: 'table',
|
||||
name: 'table',
|
||||
fields: [
|
||||
'field',
|
||||
'before',
|
||||
'after',
|
||||
],
|
||||
}
|
||||
],
|
||||
} as TableOptions;
|
||||
|
@ -4,217 +4,37 @@ import { LOG_TYPE_CREATE, LOG_TYPE_UPDATE, LOG_TYPE_DESTROY } from '../constants
|
||||
export default {
|
||||
name: 'action_logs',
|
||||
title: '操作记录',
|
||||
developerMode: true,
|
||||
internal: true,
|
||||
createdBy: false,
|
||||
updatedBy: false,
|
||||
updatedAt: false,
|
||||
logging: false,
|
||||
fields: [
|
||||
{
|
||||
interface: 'createdAt',
|
||||
name: 'created_at',
|
||||
type: 'date',
|
||||
title: '操作时间',
|
||||
showTime: true,
|
||||
component: {
|
||||
showInTable: true,
|
||||
showInDetail: true,
|
||||
},
|
||||
name: 'created_at',
|
||||
},
|
||||
{
|
||||
interface: 'linkTo',
|
||||
type: 'belongsTo',
|
||||
name: 'user',
|
||||
target: 'users',
|
||||
title: '操作用户',
|
||||
appends: true,
|
||||
labelField: 'nickname',
|
||||
component: {
|
||||
showInTable: true,
|
||||
showInDetail: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
interface: 'linkTo',
|
||||
type: 'belongsTo',
|
||||
name: 'collection',
|
||||
target: 'collections',
|
||||
title: '数据表',
|
||||
targetKey: 'name',
|
||||
appends: true,
|
||||
labelField: 'title',
|
||||
component: {
|
||||
showInTable: true,
|
||||
showInDetail: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
interface: 'select',
|
||||
type: 'string',
|
||||
name: 'type',
|
||||
title: '操作类型',
|
||||
filterable: true,
|
||||
dataSource: [
|
||||
{ value: LOG_TYPE_CREATE, label: '新增', color: 'blue' },
|
||||
{ value: LOG_TYPE_UPDATE, label: '更新', color: 'volcano' },
|
||||
{ value: LOG_TYPE_DESTROY, label: '删除', color: 'magenta' },
|
||||
],
|
||||
component: {
|
||||
showInTable: true,
|
||||
showInDetail: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'integer',
|
||||
name: 'index',
|
||||
title: '数据ID',
|
||||
component: {
|
||||
showInTable: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
interface: 'subTable',
|
||||
type: 'hasMany',
|
||||
name: 'changes',
|
||||
target: 'action_changes',
|
||||
title: '数据变动',
|
||||
component: {
|
||||
showInDetail: true,
|
||||
},
|
||||
}
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
type: 'filter',
|
||||
name: 'filter',
|
||||
title: '筛选'
|
||||
},
|
||||
{
|
||||
type: 'list',
|
||||
name: 'list',
|
||||
title: '查看',
|
||||
// sort: '-created_at'
|
||||
},
|
||||
],
|
||||
views_v2: [
|
||||
{
|
||||
developerMode: true,
|
||||
type: 'table',
|
||||
name: 'table',
|
||||
title: '全部数据',
|
||||
labelField: 'created_at',
|
||||
actions: [
|
||||
{
|
||||
name: 'filter',
|
||||
type: 'filter',
|
||||
title: '过滤',
|
||||
},
|
||||
],
|
||||
fields: ['created_at', 'user', 'collection', 'type', 'index'],
|
||||
detailsOpenMode: 'drawer', // window
|
||||
details: ['descriptions'],
|
||||
sort: ['-created_at'],
|
||||
},
|
||||
{
|
||||
developerMode: true,
|
||||
type: 'table',
|
||||
name: 'create',
|
||||
title: '新增数据',
|
||||
labelField: 'created_at',
|
||||
actions: [
|
||||
{
|
||||
name: 'filter',
|
||||
type: 'filter',
|
||||
title: '过滤',
|
||||
},
|
||||
],
|
||||
fields: ['created_at', 'user', 'collection', 'type', 'index'],
|
||||
detailsOpenMode: 'drawer', // window
|
||||
details: ['descriptions'],
|
||||
filter: {
|
||||
and: [
|
||||
{
|
||||
type: 'create',
|
||||
}
|
||||
],
|
||||
},
|
||||
sort: ['-created_at'],
|
||||
},
|
||||
{
|
||||
developerMode: true,
|
||||
type: 'table',
|
||||
name: 'update',
|
||||
title: '更新数据',
|
||||
labelField: 'created_at',
|
||||
actions: [
|
||||
{
|
||||
name: 'filter',
|
||||
type: 'filter',
|
||||
title: '过滤',
|
||||
},
|
||||
],
|
||||
fields: ['created_at', 'user', 'collection', 'type', 'index'],
|
||||
detailsOpenMode: 'drawer', // window
|
||||
details: ['descriptions'],
|
||||
filter: {
|
||||
and: [
|
||||
{
|
||||
type: 'update',
|
||||
}
|
||||
],
|
||||
},
|
||||
sort: ['-created_at'],
|
||||
},
|
||||
{
|
||||
developerMode: true,
|
||||
type: 'table',
|
||||
name: 'destroy',
|
||||
title: '删除数据',
|
||||
labelField: 'created_at',
|
||||
actions: [
|
||||
{
|
||||
name: 'filter',
|
||||
type: 'filter',
|
||||
title: '过滤',
|
||||
},
|
||||
],
|
||||
fields: ['created_at', 'user', 'collection', 'type', 'index'],
|
||||
detailsOpenMode: 'drawer', // window
|
||||
details: ['descriptions'],
|
||||
filter: {
|
||||
and: [
|
||||
{
|
||||
type: 'destroy',
|
||||
}
|
||||
],
|
||||
},
|
||||
sort: ['-created_at'],
|
||||
},
|
||||
{
|
||||
type: 'table',
|
||||
name: 'table2',
|
||||
title: '操作日志列表',
|
||||
labelField: 'created_at',
|
||||
actions: [
|
||||
{
|
||||
name: 'filter',
|
||||
type: 'filter',
|
||||
title: '过滤',
|
||||
},
|
||||
],
|
||||
fields: ['created_at', 'user', 'type', 'index'],
|
||||
detailsOpenMode: 'drawer', // window
|
||||
details: ['descriptions'],
|
||||
sort: ['-created_at'],
|
||||
},
|
||||
{
|
||||
developerMode: true,
|
||||
type: 'descriptions',
|
||||
name: 'descriptions',
|
||||
title: '详情',
|
||||
fields: ['created_at', 'user', 'collection', 'type', 'index', 'changes'],
|
||||
actions: [],
|
||||
},
|
||||
],
|
||||
} as TableOptions;
|
||||
|
@ -12,7 +12,7 @@ export default async function() {
|
||||
|
||||
// 为所有的表都加上日志的 hooks
|
||||
database.addHook('afterTableInit', (table) => {
|
||||
if (table.options.logging === false) {
|
||||
if (!table.options.logging) {
|
||||
return;
|
||||
}
|
||||
addAll(database.getModel(table.options.name));
|
||||
@ -20,7 +20,7 @@ export default async function() {
|
||||
|
||||
const Collection = database.getModel('collections');
|
||||
Collection.addHook('afterCreate', async (model, options) => {
|
||||
if (model.get('logging') === false) {
|
||||
if (!model.get('logging')) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -28,20 +28,21 @@ export default async function() {
|
||||
|
||||
const exists = await model.countFields({
|
||||
where: {
|
||||
type: { [Op.iLike]: 'hasMany' },
|
||||
dataType: { [Op.iLike]: 'hasMany' },
|
||||
name: 'action_logs'
|
||||
},
|
||||
transaction
|
||||
});
|
||||
|
||||
if (!exists) {
|
||||
await model.createField({
|
||||
await model.createSystemField({
|
||||
interface: 'linkTo',
|
||||
type: 'hasMany',
|
||||
dataType: 'hasMany',
|
||||
name: 'action_logs',
|
||||
target: 'action_logs',
|
||||
title: '数据动态',
|
||||
foreignKey: 'index',
|
||||
state: 0,
|
||||
scope: {
|
||||
collection_name: model.get('name')
|
||||
},
|
||||
|
@ -6,16 +6,17 @@ export default {
|
||||
model: 'Collection',
|
||||
sortable: 'sort',
|
||||
fields: [
|
||||
// {
|
||||
// type: 'sort',
|
||||
// name: 'sort',
|
||||
// },
|
||||
{
|
||||
type: 'uid',
|
||||
name: 'name',
|
||||
primaryKey: true,
|
||||
prefix: 't_',
|
||||
},
|
||||
{
|
||||
type: 'boolean',
|
||||
name: 'logging',
|
||||
defaultValue: true,
|
||||
},
|
||||
{
|
||||
type: 'string',
|
||||
name: 'title',
|
||||
@ -38,8 +39,29 @@ export default {
|
||||
{
|
||||
type: 'hasMany',
|
||||
name: 'fields',
|
||||
target: 'fields',
|
||||
sourceKey: 'name',
|
||||
},
|
||||
{
|
||||
type: 'hasMany',
|
||||
name: 'generalFields',
|
||||
target: 'fields',
|
||||
foreignKey: 'collection_name',
|
||||
sourceKey: 'name',
|
||||
scope: {
|
||||
state: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'hasMany',
|
||||
name: 'systemFields',
|
||||
target: 'fields',
|
||||
foreignKey: 'collection_name',
|
||||
sourceKey: 'name',
|
||||
scope: {
|
||||
state: 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'belongsTo',
|
||||
name: 'uiSchema',
|
||||
|
@ -11,18 +11,11 @@ export default {
|
||||
scope: ['parentKey'],
|
||||
},
|
||||
fields: [
|
||||
// {
|
||||
// type: 'sort',
|
||||
// name: 'sort',
|
||||
// scope: ['parentKey'],
|
||||
// },
|
||||
{
|
||||
type: 'uid',
|
||||
name: 'key',
|
||||
primaryKey: true,
|
||||
prefix: 'f_',
|
||||
// autoIncrement: false,
|
||||
// defaultValue: DataTypes.UUIDV4,
|
||||
},
|
||||
{
|
||||
type: 'string',
|
||||
@ -40,6 +33,11 @@ export default {
|
||||
type: 'string',
|
||||
name: 'privilege',
|
||||
},
|
||||
{
|
||||
type: 'integer',
|
||||
name: 'state',
|
||||
default: 1,
|
||||
},
|
||||
{
|
||||
type: 'hasMany',
|
||||
name: 'children',
|
||||
|
@ -36,12 +36,22 @@ export class Collection extends Model {
|
||||
const json = this.toJSON();
|
||||
const data: any = _.omit(json, ['options', 'created_at', 'updated_at']);
|
||||
const options = json['options'] || {};
|
||||
const fields = await this.getNestedFields();
|
||||
return { ...data, ...options, fields }
|
||||
const generalFields = await this.getNestedFields({
|
||||
where: {
|
||||
state: 1,
|
||||
}
|
||||
});
|
||||
const systemFields = await this.getNestedFields({
|
||||
where: {
|
||||
state: 0,
|
||||
}
|
||||
});
|
||||
return { ...data, ...options, generalFields, systemFields }
|
||||
}
|
||||
|
||||
async getNestedFields() {
|
||||
async getNestedFields(options) {
|
||||
const fields = await this.getFields({
|
||||
...options,
|
||||
order: [['sort', 'asc']],
|
||||
});
|
||||
const items = [];
|
||||
@ -60,8 +70,8 @@ export class Collection extends Model {
|
||||
*/
|
||||
async loadTableOptions(opts: any = {}) {
|
||||
const options = await this.toProps();
|
||||
// console.log(JSON.stringify(options, null, 2));
|
||||
const table = this.database.table(options);
|
||||
const { generalFields = [], systemFields = [], ...others } = options;
|
||||
const table = this.database.table({ ...others, fields: generalFields.concat(systemFields) });
|
||||
return table;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user