organize the code

This commit is contained in:
chenos 2021-03-18 20:58:59 +08:00
parent fcf7b367ac
commit ea07c2de32
15 changed files with 35 additions and 844 deletions

View File

@ -1,13 +0,0 @@
import { init } from '@nocobase/plugin-china-region/src/db/seeders';
import api from '../app';
(async () => {
await api.loadPlugins();
await api.database.sync();
await init(api);
})().then(() => {
process.exit(0);
}).catch(err => {
console.error(err);
process.exit(1);
});

View File

@ -1,31 +0,0 @@
import api from '../app';
import Database from '@nocobase/database';
(async () => {
await api.loadPlugins();
const database: Database = api.database;
await api.database.sync({
tables: ['views'],
});
const [Collection, View, User] = database.getModels(['collections', 'views', 'users']);
const table = database.getTable('views');
const collection = await Collection.findByName('views');
console.log(table.getOptions().fields);
await collection.updateAssociations({
fields: table.getOptions().fields,
}, {
migrate: false,
});
const views = await View.findAll();
for (const view of views) {
if (!view.get('mode')) {
if (view.get('template') === 'SimpleTable') {
view.set('mode', 'simple');
} else {
view.set('mode', 'default');
}
await view.save();
}
}
})();

View File

@ -1,181 +0,0 @@
import api from '../app';
import Database from '@nocobase/database';
import views_v2 from '@nocobase/plugin-pages/src/collections/views_v2';
import { Op } from 'sequelize';
(async () => {
await api.loadPlugins();
const database: Database = api.database;
await api.database.sync();
await api.database.getModel('collections').load({skipExisting: true});
const [Collection, Field, Page, Menu, View] = database.getModels(['collections', 'fields', 'pages_v2', 'menus', 'views_v2']);
// await Collection.import(require('./collections/authors').default, { update: true });
// await Collection.import(require('./collections/books').default, { update: true });
await Menu.truncate();
await Page.destroy({
where: {
id: {
[Op.not]: null,
},
}
});
await View.destroy({
where: {
id: {
[Op.not]: null,
},
}
});
const collection = await Collection.findOne({
where: {
name: 'views_v2',
}
});
await collection.updateAssociations({
fields: views_v2.fields,
views_v2: views_v2.views_v2,
});
// const authors = require('./collections/authors').default;
console.log('views_v2.fields', views_v2.fields.map(field=>field.name));
// await collection.updateAssociations({
// views_v2: authors.views_v2,
// });
const tables = database.getTables([
'collections',
'fields',
'menus',
'pages_v2',
'views_v2',
'pages_views_v2',
'automations',
'automations_jobs',
'action_logs',
'users',
'roles',
'scopes',
'views_actions_v2',
'views_pages_v2',
'views_fields_v2',
]);
for (let table of tables) {
console.log(table.getName());
await Collection.import(table.getOptions(), { update: true, migrate: false });
}
const menus = [
{
title: '仪表盘',
icon: 'DashboardOutlined',
type: 'group',
children: [
{
title: '欢迎光临',
icon: 'DatabaseOutlined',
type: 'page',
pageName: 'welcome'
},
],
},
{
title: '数据',
icon: 'DatabaseOutlined',
type: 'group',
children: [
{
title: '作者',
icon: 'DatabaseOutlined',
type: 'page',
pageName: 'authors.all',
},
{
title: '申请表单',
icon: 'DatabaseOutlined',
type: 'page',
pageName: 'authors.form',
},
],
},
{
title: '用户',
icon: 'TeamOutlined',
type: 'group',
children: [
{
title: '用户管理',
icon: 'DatabaseOutlined',
type: 'page',
pageName: 'users.all',
},
],
},
{
title: '动态',
icon: 'NotificationOutlined',
type: 'group',
children: [
{
title: '操作日志',
icon: 'DatabaseOutlined',
type: 'page',
pageName: 'action_logs.all',
},
],
},
{
title: '配置',
icon: 'SettingOutlined',
type: 'group',
children: [
{
title: '数据表配置',
icon: 'DatabaseOutlined',
type: 'page',
pageName: 'collections.all',
},
{
title: '菜单配置',
icon: 'MenuOutlined',
type: 'page',
pageName: 'menus.all',
},
{
title: '页面配置',
icon: 'MenuOutlined',
type: 'page',
pageName: 'pages_v2.globals',
},
{
title: '权限配置',
icon: 'MenuOutlined',
type: 'page',
pageName: 'roles.all',
},
{
title: '自动化配置',
icon: 'MenuOutlined',
type: 'page',
pageName: 'automations.all',
},
],
},
];
for (const item of menus) {
const menu = await Menu.create(item);
await menu.updateAssociations(item);
}
})();

View File

@ -1,65 +0,0 @@
import api from '../app';
import Database from '@nocobase/database';
(async () => {
await api.loadPlugins();
const database: Database = api.database;
await api.database.sync();
const [Collection, Page, Role] = database.getModels(['collections', 'pages', 'roles']);
const tables = database.getTables();
for (let table of tables) {
console.log(table.getName());
await Collection.import(table.getOptions(), { update: true, migrate: false });
}
const parent = await Page.findOne({
where: {
path: '/settings',
}
});
const roles = await Role.bulkCreate([
{ title: '系统开发组' },
{ title: '数据管理组' },
{ title: '普通用户组' },
{ title: '未登录用户组' },
]);
await Page.create({
title: '权限组配置',
type: 'collection',
collection: 'roles',
path: '/settings/roles',
icon: 'TableOutlined',
sort: 120,
showInMenu: true,
parent_id: parent.id,
});
const Scope = database.getModel('scopes');
const collections = await Collection.findAll();
for (const collection of collections) {
const count = await collection.countScopes();
if (count === 0) {
await Scope.bulkCreate([
{
title: '全部数据',
filter: {},
collection_name: collection.name,
},
{
title: '用户自己的数据',
filter: {
"created_by_id.$currentUser": true,
},
collection_name: collection.name,
},
]);
}
}
})();

View File

@ -1,36 +0,0 @@
import api from '../app';
import Database from '@nocobase/database';
(async () => {
await api.loadPlugins();
const database: Database = api.database;
await api.database.sync({
// tables: ['roles'],
});
const [Collection, User, Role] = database.getModels(['collections', 'users', 'roles']);
const tables = database.getTables();
for (let table of tables) {
console.log(table.getName());
await Collection.import(table.getOptions(), { update: true, migrate: false });
}
let user = await User.findOne({
where: {
username: "admin",
},
});
const role = await Role.findOne({
where: {
title: '系统开发组',
}
});
role.set('type', -1);
await role.save();
await user.setRoles([role]);
})();

View File

@ -1,42 +0,0 @@
import api from '../app';
import Database from '@nocobase/database';
(async () => {
await api.loadPlugins();
const database: Database = api.database;
await api.database.sync({
tables: ['scopes', 'action_logs', 'action_changes'],
});
const [Collection, Page] = database.getModels(['collections', 'pages']);
const tables = database.getTables(['scopes', 'action_logs', 'action_changes']);
for (let table of tables) {
console.log(table.getName());
await Collection.import(table.getOptions(), { update: true, migrate: false });
}
await Page.import({
title: '动态',
type: 'layout',
path: '/activity',
icon: 'NotificationOutlined',
template: 'SideMenuLayout',
sort: 85,
showInMenu: true,
parent_id: 1,
children: [
{
title: '操作记录',
type: 'collection',
path: '/activity/logs',
icon: 'HistoryOutlined',
template: 'collection',
collection: 'action_logs',
sort: 80,
showInMenu: true,
},
]
});
})();

View File

@ -1,19 +0,0 @@
import api from '../app';
import Database from '@nocobase/database';
(async () => {
await api.loadPlugins();
const database: Database = api.database;
await api.database.sync({
tables: ['automations', 'automations_jobs', 'actions_scopes'],
});
const [Collection, User, Role] = database.getModels(['collections', 'users', 'roles']);
const tables = database.getTables(['automations', 'automations_jobs', 'actions_scopes']);
for (let table of tables) {
console.log(table.getName());
await Collection.import(table.getOptions(), { update: true, migrate: false });
}
})();

View File

@ -170,12 +170,40 @@ const data = [
developerMode: true,
children: [
{
title: '操作日志',
title: '数据动态',
icon: 'DatabaseOutlined',
type: 'page',
views: ['action_logs.table'],
type: 'group',
developerMode: true,
name: 'auditing',
children: [
{
title: '全部数据',
type: 'page',
views: ['action_logs.table'],
developerMode: true,
name: 'auditing',
},
{
title: '新增数据',
type: 'page',
views: ['action_logs.create'],
developerMode: true,
name: 'create-auditing',
},
{
title: '更新数据',
type: 'page',
views: ['action_logs.update'],
developerMode: true,
name: 'update-auditing',
},
{
title: '删除数据',
type: 'page',
views: ['action_logs.destroy'],
developerMode: true,
name: 'destroy-auditing',
},
],
},
],
},

View File

@ -5,15 +5,14 @@ import Database from '@nocobase/database';
await api.loadPlugins();
const database: Database = api.database;
await api.database.sync({
tables: ['scopes'],
});
const [Collection, User, Role] = database.getModels(['collections', 'users', 'roles']);
const [Collection] = database.getModels(['collections']);
const tables = database.getTables(['scopes']);
const tables = database.getTables();
for (let table of tables) {
console.log(table.getName());
await Collection.import(table.getOptions(), { update: true, migrate: false });
await Collection.import(table.getOptions(), { migrate: false });
}
})();

View File

@ -1,120 +0,0 @@
import React, { useState } from 'react'
import { connect } from '@formily/react-schema-renderer'
import { Select, Drawer, Button, Space } from 'antd'
import {
mapStyledProps,
mapTextComponent,
compose,
isStr,
isArr
} from '../shared'
import ViewFactory from '@/components/views'
function transform({value, multiple, labelField, valueField = 'id'}) {
let selectedKeys = [];
let selectedValue = [];
const values = Array.isArray(value) ? value : [value].filter(Boolean);
selectedKeys = values.map(item => item[valueField]);
selectedValue = values.map(item => {
return {
value: item[valueField],
label: item[labelField],
}
});
console.log({selectedKeys, selectedValue, values, labelField, valueField})
if (!multiple) {
return [selectedKeys.shift(), selectedValue.shift()];
}
return [selectedKeys, selectedValue];
}
export function Scope(props) {
const { resourceTarget, target, multiple, associatedName, associatedKey, labelField, valueField = 'id', value, onChange } = props;
const [selectedKeys, selectedValue] = transform({value, multiple, labelField, valueField });
const [visible, setVisible] = useState(false);
const [selectedRowKeys, setSelectedRowKeys] = useState(multiple ? selectedKeys : [selectedKeys]);
const [selectedRows, setSelectedRows] = useState(selectedValue);
const [options, setOptions] = useState(selectedValue);
console.log('valuevaluevaluevaluevaluevalue', selectedValue, value);
return (
<>
<Select
size={'small'}
open={false}
mode={multiple ? 'tags' : undefined}
labelInValue
allowClear={true}
value={options}
placeholder={'默认为全部数据'}
notFoundContent={''}
onChange={(data) => {
setOptions(data);
if (Array.isArray(data)) {
const srks = data.map(item => item.value);
onChange(srks);
setSelectedRowKeys(srks);
console.log('datadatadatadata', {data, srks});
} else if (data && typeof data === 'object') {
onChange(data.value);
setSelectedRowKeys([data.value]);
} else {
console.log(data);
onChange(null);
setSelectedRowKeys([]);
}
}}
onClick={() => {
setVisible(true);
}}
></Select>
<Drawer
width={'40%'}
className={'noco-drawer'}
title={'可操作的数据范围'}
visible={visible}
bodyStyle={{padding: 0}}
onClose={() => {
setVisible(false);
}}
footer={[
<div
style={{
textAlign: 'right',
}}
>
<Space>
<Button onClick={() => setVisible(false)}></Button>
<Button type={'primary'} onClick={() => {
setOptions(selectedRows);
// console.log('valuevaluevaluevaluevaluevalue', {selectedRowKeys});
onChange(multiple ? selectedRowKeys : selectedRowKeys.shift());
setVisible(false);
}}></Button>
</Space>
</div>
]}
>
<ViewFactory
multiple={multiple}
associatedName={associatedName}
associatedKey={associatedKey}
resourceName={target}
resourceTarget={resourceTarget}
isFieldComponent={true}
selectedRowKeys={selectedRowKeys}
onSelected={(values) => {
// 需要返回的是 array
const [selectedKeys, selectedValue] = transform({value: values, multiple: true, labelField, valueField });
setSelectedRows(selectedValue);
setSelectedRowKeys(selectedKeys);
// console.log('valuevaluevaluevaluevaluevalue', {values, selectedKeys, selectedValue});
}}
// associatedKey={}
// associatedName={associatedName}
viewName={'table'}
/>
</Drawer>
</>
);
}

View File

@ -8,7 +8,6 @@ import { useDynamicList } from 'ahooks';
import findIndex from 'lodash/findIndex';
import get from 'lodash/get';
import set from 'lodash/set';
import { Scope } from './Scope';
import { DrawerSelectComponent } from '../drawer-select';
export const Permissions = {} as {Actions: any, Fields: any, Tabs: any};

View File

@ -24,7 +24,6 @@ import { Permissions } from './permissions'
import { DraggableTable } from './draggable-table'
import { Values } from './values'
import { Automations } from './automations'
import { VirtualTable } from './virtual-table'
import { Wysiwyg } from './wysiwyg'
export const setup = () => {
@ -70,6 +69,5 @@ export const setup = () => {
'automations.datetime': Automations.DateTime,
'automations.endmode': Automations.EndMode,
'automations.cron': Automations.Cron,
'virtualTable': VirtualTable,
});
}

View File

@ -1,52 +0,0 @@
import React, { useState } from 'react';
import { Tooltip, Button } from 'antd';
import {
SchemaForm,
SchemaMarkupField as Field,
createFormActions,
createAsyncFormActions,
Submit,
Reset,
FormButtonGroup,
registerFormFields,
FormValidator,
setValidationLanguage,
} from '@formily/antd';
import { QuestionCircleOutlined } from '@ant-design/icons';
import scopes from '@/components/views/Form/scopes';
import { fields2properties } from '@/components/pages/AdminLoader/View/Form';
import Drawer from '@/components/pages/AdminLoader/Drawer';
export function Form(props: any) {
const { data, onFinish } = props;
const { fields = [] } = props.schema||{};
return (
<SchemaForm
colon={true}
layout={'vertical'}
initialValues={data}
// actions={actions}
onReset={async () => {
// setData({filter: {}});
onFinish && await onFinish(null);
}}
onSubmit={async (values) => {
if (onFinish) {
await onFinish(values);
}
}}
schema={{
type: 'object',
properties: fields2properties(fields),
}}
expressionScope={scopes}
>
<FormButtonGroup align={'end'}>
<Reset></Reset>
<Submit></Submit>
</FormButtonGroup>
</SchemaForm>
);
}
export default Form;

View File

@ -1,254 +0,0 @@
import React, { useEffect, useRef, useState } from 'react';
import ReactDOM from 'react-dom';
import { Table as AntdTable, Button, Space, Popconfirm } from 'antd';
import { Actions } from '@/components/actions';
import ViewFactory from '@/components/views';
import { useRequest } from 'umi';
import api from '@/api-client';
import { components, fields2columns } from '@/components/views/SortableTable';
import Form from './Form';
import { Spin } from '@nocobase/client';
import maxBy from 'lodash/maxBy';
import Drawer from '@/components/pages/AdminLoader/Drawer';
import ReactDragListView from 'react-drag-listview';
import arrayMove from 'array-move';
import get from 'lodash/get';
import findIndex from 'lodash/findIndex';
import { FilterOutlined, PlusOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons';
export interface SimpleTableProps {
schema?: any;
activeTab?: any;
resourceName: string;
associatedName?: string;
associatedKey?: string;
[key: string]: any;
}
const schema = {
talbe: {
fields: [
{
interface: 'sort',
type: 'sort',
name: 'sort',
title: '排序',
component: {},
},
// {
// interface: 'string',
// type: 'string',
// name: 'name',
// title: '视图',
// component: {
// type: 'string',
// },
// },
{
interface: 'linkTo',
type: 'string',
name: 'view',
target: 'views_v2',
// foreignKey: 'pageName',
// targetKey: 'id',
title: '视图',
labelField: 'title',
valueField: 'name',
multiple: false,
component: {
type: 'drawerSelect',
'x-component-props': {
viewName: 'views_v2.table',
resourceName: 'views_v2',
labelField: 'title',
valueField: 'name',
},
},
},
{
interface: 'radio',
type: 'string',
name: 'width',
title: '宽度',
dataSource: [
{ label: '50%', value: '50%' },
{ label: '100%', value: '100%' },
],
component: {
type: 'radio',
},
}
]
},
form: {
fields: [
// {
// interface: 'string',
// type: 'string',
// name: 'name',
// title: '视图',
// component: {
// type: 'string',
// },
// },
{
interface: 'linkTo',
type: 'belongsTo',
name: 'view',
target: 'views_v2',
// foreignKey: 'pageName',
// targetKey: 'id',
title: '视图',
labelField: 'title',
valueField: 'name',
multiple: false,
component: {
type: 'drawerSelect',
'x-component-props': {
multiple: false,
viewName: 'views_v2.table',
resourceName: 'views_v2',
labelField: 'title',
valueField: 'name',
},
},
},
{
interface: 'radio',
type: 'string',
name: 'width',
title: '宽度',
dataSource: [
{ label: '50%', value: '50%' },
{ label: '100%', value: '100%' },
],
component: {
type: 'radio',
},
}
],
},
};
export function generateIndex(): string {
return `${Math.random().toString(36).replace('0.', '').slice(-4).padStart(4, '0')}`;
}
export default function Table(props: SimpleTableProps) {
console.log({props});
const { associatedKey, rowKey = '__index', value, onChange } = props;
const [dataSource, setDataSource] = useState(() => {
if (!Array.isArray(value)) {
return [];
}
return value.map((item: any) => {
if (typeof item === 'string') {
item = { name: item };
}
if (!item.__index) {
item.__index = generateIndex();
}
return item;
});
});
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
const columns = fields2columns(schema.talbe.fields);
console.log({value});
const dragProps = {
async onDragEnd(fromIndex, toIndex) {
const list = dataSource;
const newList = arrayMove(list, fromIndex, toIndex);
setDataSource(newList);
console.log({fromIndex, toIndex, newList});
},
handleSelector: ".drag-handle",
ignoreSelector: "tr.ant-table-expanded-row",
nodeSelector: "tr.ant-table-row"
};
return (
<div>
<Popconfirm title="确认删除吗?" onConfirm={async () => {
const data = dataSource.filter(item => !selectedRowKeys.includes(item.__index));
setDataSource(data);
}}>
<Button
danger
type={'ghost'}
icon={<DeleteOutlined/>}
></Button>
</Popconfirm>
<Button icon={<PlusOutlined/>} type={'primary'} onClick={() => {
Drawer.open({
title: 'xx',
content: ({ resolve }) => {
return (
<>
<Form onFinish={(values) => {
const data = [...dataSource];
data.push({
...values,
__index: generateIndex(),
});
setDataSource(data);
onChange(data);
resolve();
}} schema={{
fields: schema.form.fields,
}}/>
</>
)
}
})
}}></Button>
<ReactDragListView {...dragProps}>
<AntdTable
rowKey={rowKey}
pagination={false}
size={'small'}
columns={columns}
dataSource={dataSource}
rowSelection={{
selectedRowKeys,
onChange(selectedRowKeys) {
setSelectedRowKeys(selectedRowKeys);
}
}}
onRow={(record) => {
return {
onClick() {
Drawer.open({
title: 'xx',
content: ({ resolve }) => {
return (
<>
<Form onFinish={(values) => {
const index = findIndex(dataSource, item => item.__index === values.__index);
const data = [...dataSource];
if (index === -1) {
return;
}
data[index] = values;
console.log({values, index, data})
setDataSource(data);
onChange(data);
// if (index >= 0) {
// dataSource[index] = values;
// setDataSource({...dataSource});
// }
resolve();
}} data={record} schema={{
fields: schema.form.fields,
}}/>
</>
)
}
})
}
}
}}
/>
</ReactDragListView>
</div>
);
}

View File

@ -1,20 +0,0 @@
import React, { useRef } from 'react'
import { connect } from '@formily/react-schema-renderer'
import moment from 'moment'
import { Select, Button, Table as AntdTable } from 'antd'
import {
mapStyledProps,
mapTextComponent,
compose,
isStr,
isArr
} from '../shared'
import ViewFactory from '@/components/views';
import Table from './Table';
export const VirtualTable = connect({
getProps: mapStyledProps,
getComponent: mapTextComponent,
})(Table)
export default VirtualTable