mirror of
https://github.com/nocobase/nocobase
synced 2024-11-15 04:45:56 +00:00
chore: add prettier config
This commit is contained in:
parent
d80c875d5e
commit
f199df96aa
8
.prettierignore
Normal file
8
.prettierignore
Normal file
@ -0,0 +1,8 @@
|
||||
**/*.md
|
||||
**/*.svg
|
||||
**/*.ejs
|
||||
**/*.html
|
||||
package.json
|
||||
.umi
|
||||
.umi-production
|
||||
.umi-test
|
11
.prettierrc
Normal file
11
.prettierrc
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all",
|
||||
"printWidth": 80,
|
||||
"overrides": [
|
||||
{
|
||||
"files": ".prettierrc",
|
||||
"options": { "parser": "json" }
|
||||
}
|
||||
]
|
||||
}
|
@ -12,9 +12,7 @@ export class ClientSDK {
|
||||
return this.options.request(url, options || {});
|
||||
}
|
||||
|
||||
resource(name) {
|
||||
|
||||
}
|
||||
resource(name) {}
|
||||
}
|
||||
|
||||
export default ClientSDK;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { createContext } from 'react'
|
||||
import React, { createContext } from 'react';
|
||||
// import { ConfigProvider as AntdConfigProvider } from 'antd';
|
||||
// import enUS from 'antd/lib/locale/en_US';
|
||||
// import zhCN from 'antd/lib/locale/zh_CN';
|
||||
@ -11,9 +11,5 @@ const ConfigContext = createContext<any>(null);
|
||||
|
||||
export function ConfigProvider(props: any) {
|
||||
const { client } = props;
|
||||
return (
|
||||
<ClientProvider client={client}>
|
||||
{props.children}
|
||||
</ClientProvider>
|
||||
)
|
||||
};
|
||||
return <ClientProvider client={client}>{props.children}</ClientProvider>;
|
||||
}
|
||||
|
@ -81,9 +81,12 @@ const useActionPermissionResource = ({ onSuccess }) => {
|
||||
console.log('RoleContext', role);
|
||||
// const { props } = useTable();
|
||||
const ctx = useContext(TableRowContext);
|
||||
const resource = useResourceRequest({
|
||||
const resource = useResourceRequest(
|
||||
{
|
||||
resourceName: 'action_permissions',
|
||||
}, ActionPermissionResource);
|
||||
},
|
||||
ActionPermissionResource,
|
||||
);
|
||||
const service = useRequest(
|
||||
(params?: any) => {
|
||||
return resource.list({
|
||||
@ -593,7 +596,11 @@ function CreateFieldButton() {
|
||||
option.children.length > 0 && (
|
||||
<Menu.SubMenu key={groupIndex} title={option.label}>
|
||||
{option.children.map((item) => (
|
||||
<Menu.Item disabled={item.disabled} style={{ minWidth: 120 }} key={item.name}>
|
||||
<Menu.Item
|
||||
disabled={item.disabled}
|
||||
style={{ minWidth: 120 }}
|
||||
key={item.name}
|
||||
>
|
||||
{item.title}
|
||||
</Menu.Item>
|
||||
))}
|
||||
|
@ -51,7 +51,7 @@ const schema: ISchema = {
|
||||
type: 'void',
|
||||
title: `系统配置`,
|
||||
'x-component': 'Menu.Action',
|
||||
"x-component-props": {
|
||||
'x-component-props': {
|
||||
icon: 'SettingOutlined',
|
||||
},
|
||||
properties: {
|
||||
|
@ -22,15 +22,12 @@ export const MenuPermissionTable = observer((props) => {
|
||||
const role = useContext(RoleContext);
|
||||
const [allUiSchemaKyes, setAllUiSchemaKyes] = useState([]);
|
||||
const [uiSchemaKyes, setUiSchemaKeys] = useState([]);
|
||||
const { data, loading } = useRequest(
|
||||
'ui_schemas:getMenuItems',
|
||||
{
|
||||
const { data, loading } = useRequest('ui_schemas:getMenuItems', {
|
||||
formatResult: (data) => data?.data,
|
||||
onSuccess(data) {
|
||||
setAllUiSchemaKyes(getKeys(data));
|
||||
},
|
||||
},
|
||||
);
|
||||
});
|
||||
console.log('allUiSchemaKyes', allUiSchemaKyes);
|
||||
const resource = useResourceRequest({
|
||||
associatedName: 'roles',
|
||||
|
@ -72,9 +72,12 @@ const useActionPermissionResource = ({ onSuccess }) => {
|
||||
console.log('RoleContext', role);
|
||||
// const { props } = useTable();
|
||||
const ctx = useContext(TableRowContext);
|
||||
const resource = useResourceRequest({
|
||||
const resource = useResourceRequest(
|
||||
{
|
||||
resourceName: 'action_permissions',
|
||||
}, ActionPermissionResource);
|
||||
},
|
||||
ActionPermissionResource,
|
||||
);
|
||||
const service = useRequest(
|
||||
(params?: any) => {
|
||||
return resource.list({
|
||||
@ -292,7 +295,7 @@ const schema: ISchema = {
|
||||
icon: 'DeleteOutlined',
|
||||
confirm: {
|
||||
title: '删除数据',
|
||||
content: '删除后无法恢复,确定要删除吗?'
|
||||
content: '删除后无法恢复,确定要删除吗?',
|
||||
},
|
||||
useAction: '{{ Table.useTableDestroyAction }}',
|
||||
},
|
||||
@ -467,7 +470,7 @@ const schema: ISchema = {
|
||||
type: 'link',
|
||||
confirm: {
|
||||
title: '删除数据',
|
||||
content: '删除后无法恢复,确定要删除吗?'
|
||||
content: '删除后无法恢复,确定要删除吗?',
|
||||
},
|
||||
useAction: '{{ Table.useTableDestroyAction }}',
|
||||
},
|
||||
|
@ -64,7 +64,9 @@ export const UserInfo = () => {
|
||||
</Menu.Item>
|
||||
<Menu.Item>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
|
||||
<span style={{ marginRight: 16, display: 'inline-block' }}>角色切换</span>
|
||||
<span style={{ marginRight: 16, display: 'inline-block' }}>
|
||||
角色切换
|
||||
</span>
|
||||
<Select
|
||||
className={'roles-select'}
|
||||
bordered={false}
|
||||
@ -82,7 +84,9 @@ export const UserInfo = () => {
|
||||
</Menu.Item>
|
||||
<Menu.Item>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
|
||||
<span style={{ marginRight: 16, display: 'inline-block' }}>语言设置</span>
|
||||
<span style={{ marginRight: 16, display: 'inline-block' }}>
|
||||
语言设置
|
||||
</span>
|
||||
<Select
|
||||
className={'roles-select'}
|
||||
bordered={false}
|
||||
|
@ -36,7 +36,7 @@ import {
|
||||
} from '../../constate';
|
||||
import { uid } from '@formily/shared';
|
||||
import { Permissions } from './Permissions';
|
||||
import { Collections } from './Collections'
|
||||
import { Collections } from './Collections';
|
||||
import { More } from './More';
|
||||
import { UserInfo } from './UserInfo';
|
||||
import {
|
||||
@ -232,7 +232,6 @@ export function AdminLayout({ route, ...others }: any) {
|
||||
}, []);
|
||||
};
|
||||
|
||||
|
||||
if (loading) {
|
||||
return <Spin size={'large'} className={'nb-spin-center'} />;
|
||||
}
|
||||
|
@ -75,7 +75,8 @@
|
||||
.user-info {
|
||||
height: 46px;
|
||||
color: #fff;
|
||||
&:hover, &:focus {
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
@ -95,7 +96,8 @@
|
||||
}
|
||||
|
||||
.site-header {
|
||||
.ant-menu.ant-menu-dark .ant-menu-item-selected, .ant-menu-submenu-popup.ant-menu-dark .ant-menu-item-selected {
|
||||
.ant-menu.ant-menu-dark .ant-menu-item-selected,
|
||||
.ant-menu-submenu-popup.ant-menu-dark .ant-menu-item-selected {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
.ant-menu-dark.ant-menu-horizontal > .ant-menu-item:hover {
|
||||
@ -105,7 +107,7 @@
|
||||
color: rgba(255, 255, 255, 0.65) !important;
|
||||
&.nb-designable-toggle:hover {
|
||||
color: #fff !important;
|
||||
background-color: #F18B62 !important
|
||||
background-color: #f18b62 !important;
|
||||
}
|
||||
}
|
||||
.ant-btn:hover {
|
||||
|
@ -11,7 +11,7 @@ const RouteSwitch = createRouteSwitch({
|
||||
components: {
|
||||
Home: (props) => {
|
||||
console.log({ props });
|
||||
return <div>Home {props.children}</div>
|
||||
return <div>Home {props.children}</div>;
|
||||
},
|
||||
Login: () => <div>Login</div>,
|
||||
},
|
||||
|
@ -22,7 +22,7 @@ export interface RouteProps {
|
||||
strict?: boolean;
|
||||
sensitive?: boolean;
|
||||
component?: any;
|
||||
routes?: RouteProps[],
|
||||
routes?: RouteProps[];
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ export function ClientProvider(props) {
|
||||
export function useResourceRequest(options, ResourceClass?: any) {
|
||||
const Cls = ResourceClass || Resource;
|
||||
const { request } = useClient();
|
||||
return Cls.make(options, request);;
|
||||
return Cls.make(options, request);
|
||||
}
|
||||
|
||||
export function useClient() {
|
||||
|
@ -1,12 +1,14 @@
|
||||
import { useRequest } from 'ahooks';
|
||||
import constate from 'constate';
|
||||
|
||||
const [CollectionsProvider, useCollectionsContext] = constate<any, any, any>(() => {
|
||||
const [CollectionsProvider, useCollectionsContext] = constate<any, any, any>(
|
||||
() => {
|
||||
const result = useRequest('collections:findAll', {
|
||||
formatResult: (result) => result?.data,
|
||||
});
|
||||
return {
|
||||
...result, collections: result.data || [],
|
||||
...result,
|
||||
collections: result.data || [],
|
||||
findCollection(name) {
|
||||
return result?.data?.find((item) => item.name === name);
|
||||
},
|
||||
@ -17,11 +19,14 @@ const [CollectionsProvider, useCollectionsContext] = constate<any, any, any>(()
|
||||
}));
|
||||
},
|
||||
getFieldsByCollection(collectionName) {
|
||||
const collection = result?.data?.find((item) => item.name === collectionName);
|
||||
const collection = result?.data?.find(
|
||||
(item) => item.name === collectionName,
|
||||
);
|
||||
return collection?.generalFields;
|
||||
},
|
||||
};
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
export { CollectionsProvider, useCollectionsContext };
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { useCookieState } from "ahooks";
|
||||
import { useCookieState } from 'ahooks';
|
||||
import constate from 'constate';
|
||||
|
||||
const [DesignableSwitchProvider, useDesignableSwitchContext] = constate(() => {
|
||||
@ -8,8 +8,8 @@ const [DesignableSwitchProvider, useDesignableSwitchContext] = constate(() => {
|
||||
designable: active === 'true',
|
||||
setDesignable(value) {
|
||||
setActive(value ? 'true' : 'false');
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
export { DesignableSwitchProvider, useDesignableSwitchContext };
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { createContext } from "react";
|
||||
import { Schema } from "@formily/react";
|
||||
import { createContext } from 'react';
|
||||
import { Schema } from '@formily/react';
|
||||
|
||||
export const VisibleContext = createContext<any>([]);
|
||||
export const BlockSchemaContext = createContext<Schema>(null);
|
||||
|
@ -1,9 +1,7 @@
|
||||
import { useRequest } from 'ahooks';
|
||||
import { Spin } from 'antd';
|
||||
import React, { useMemo } from 'react';
|
||||
import {
|
||||
MemoryRouter as Router,
|
||||
} from 'react-router-dom';
|
||||
import { MemoryRouter as Router } from 'react-router-dom';
|
||||
import {
|
||||
createRouteSwitch,
|
||||
RouteRedirectProps,
|
||||
@ -11,7 +9,7 @@ import {
|
||||
AuthLayout,
|
||||
RouteSchemaRenderer,
|
||||
ConfigProvider,
|
||||
ClientSDK
|
||||
ClientSDK,
|
||||
} from '../';
|
||||
import { UseRequestProvider } from 'ahooks';
|
||||
import { extend } from 'umi-request';
|
||||
@ -53,7 +51,7 @@ const App = () => {
|
||||
});
|
||||
|
||||
if (loading) {
|
||||
return <Spin size={'large'} className={'nb-spin-center'} />
|
||||
return <Spin size={'large'} className={'nb-spin-center'} />;
|
||||
}
|
||||
|
||||
return (
|
||||
@ -71,4 +69,4 @@ export default () => {
|
||||
<App />
|
||||
</ConfigProvider>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
@ -1 +1 @@
|
||||
export default {}
|
||||
export default {};
|
||||
|
@ -1 +1 @@
|
||||
export default {}
|
||||
export default {};
|
||||
|
@ -28,13 +28,12 @@ export interface ListOptions {
|
||||
}
|
||||
|
||||
export class Resource {
|
||||
|
||||
public options: ResourceOptions;
|
||||
public request: RequestMethod;
|
||||
|
||||
constructor(options: string | ResourceOptions, request?: any) {
|
||||
if (typeof options === 'string') {
|
||||
this.options = { resourceName: options }
|
||||
this.options = { resourceName: options };
|
||||
} else {
|
||||
this.options = options;
|
||||
}
|
||||
@ -54,7 +53,14 @@ export class Resource {
|
||||
}
|
||||
|
||||
list(options: ListOptions = {}) {
|
||||
const { defaultAppends = [], appends = [], defaultFilter, filter, pageSize, ...others } = options;
|
||||
const {
|
||||
defaultAppends = [],
|
||||
appends = [],
|
||||
defaultFilter,
|
||||
filter,
|
||||
pageSize,
|
||||
...others
|
||||
} = options;
|
||||
const { associatedKey, associatedName, resourceName } = this.options;
|
||||
let url = `${resourceName}:list`;
|
||||
if (associatedName && associatedKey) {
|
||||
@ -63,7 +69,9 @@ export class Resource {
|
||||
return this.request(url, {
|
||||
method: 'get',
|
||||
params: {
|
||||
filter: decodeURIComponent(JSON.stringify({ and: [defaultFilter, filter].filter(Boolean) })),
|
||||
filter: decodeURIComponent(
|
||||
JSON.stringify({ and: [defaultFilter, filter].filter(Boolean) }),
|
||||
),
|
||||
'fields[appends]': defaultAppends.concat(appends).join(','),
|
||||
perPage: pageSize,
|
||||
...others,
|
||||
@ -90,7 +98,7 @@ export class Resource {
|
||||
const { associatedKey, associatedName, resourceName } = this.options;
|
||||
let url = `${resourceName}:create`;
|
||||
if (associatedKey && associatedName) {
|
||||
url = `${associatedName}/${associatedKey}/${url}`
|
||||
url = `${associatedName}/${associatedKey}/${url}`;
|
||||
}
|
||||
return this.request(url, {
|
||||
method: 'post',
|
||||
@ -101,9 +109,11 @@ export class Resource {
|
||||
save(values: any, options: SaveOptions = {}) {
|
||||
const resourceKey = options.resourceKey || this.options.resourceKey;
|
||||
const { associatedKey, associatedName, resourceName } = this.options;
|
||||
let url = `${resourceName}:${resourceKey ? `update/${resourceKey}` : 'create'}`;
|
||||
let url = `${resourceName}:${
|
||||
resourceKey ? `update/${resourceKey}` : 'create'
|
||||
}`;
|
||||
if (associatedKey && associatedName) {
|
||||
url = `${associatedName}/${associatedKey}/${url}`
|
||||
url = `${associatedName}/${associatedKey}/${url}`;
|
||||
}
|
||||
return this.request(url, {
|
||||
method: 'post',
|
||||
@ -122,9 +132,13 @@ export class Resource {
|
||||
...others,
|
||||
},
|
||||
parseResponse: false,
|
||||
responseType: 'blob'
|
||||
responseType: 'blob',
|
||||
}).then(async (response: Response) => {
|
||||
const filename = decodeURI(response.headers.get('Content-Disposition').replace('attachment; filename=', ''));
|
||||
const filename = decodeURI(
|
||||
response.headers
|
||||
.get('Content-Disposition')
|
||||
.replace('attachment; filename=', ''),
|
||||
);
|
||||
// ReadableStream
|
||||
let res = new Response(response.body);
|
||||
let blob = await res.blob();
|
||||
@ -151,7 +165,7 @@ export class Resource {
|
||||
return this.request(url, {
|
||||
method: 'get',
|
||||
params: {
|
||||
filter
|
||||
filter,
|
||||
},
|
||||
});
|
||||
}
|
||||
@ -165,7 +179,10 @@ export class Resource {
|
||||
});
|
||||
}
|
||||
|
||||
static make(options: null | string | Resource | ResourceOptions, request?: any): Resource | null {
|
||||
static make(
|
||||
options: null | string | Resource | ResourceOptions,
|
||||
request?: any,
|
||||
): Resource | null {
|
||||
if (typeof options === 'string') {
|
||||
return new this({ resourceName: options }, request);
|
||||
}
|
||||
|
@ -81,7 +81,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.designable-bar-actions {
|
||||
.ant-btn {
|
||||
border: 0;
|
||||
|
@ -1566,7 +1566,10 @@ AddNew.FormItem = observer((props: any) => {
|
||||
const values = await FormDialog(`添加字段`, () => {
|
||||
return (
|
||||
<FormLayout layout={'vertical'}>
|
||||
<SchemaField scope={{ loadCollections }} schema={item} />
|
||||
<SchemaField
|
||||
scope={{ loadCollections }}
|
||||
schema={item}
|
||||
/>
|
||||
</FormLayout>
|
||||
);
|
||||
}).open({
|
||||
|
@ -7,7 +7,11 @@ import {
|
||||
getSchemaPath,
|
||||
useDesignable,
|
||||
} from '../../components/schema-renderer';
|
||||
import { useClient, DisplayedMapProvider, useDisplayedMapContext } from '../../constate';
|
||||
import {
|
||||
useClient,
|
||||
DisplayedMapProvider,
|
||||
useDisplayedMapContext,
|
||||
} from '../../constate';
|
||||
import cls from 'classnames';
|
||||
import { Button, Dropdown, Menu, Space } from 'antd';
|
||||
import SwitchMenuItem from '../../components/SwitchMenuItem';
|
||||
|
@ -1,4 +1,4 @@
|
||||
const now = new Date()
|
||||
const now = new Date();
|
||||
|
||||
export default [
|
||||
{
|
||||
@ -177,4 +177,4 @@ export default [
|
||||
start: new Date(2015, 3, 14, 18, 30, 0),
|
||||
end: new Date(2015, 3, 14, 20, 0, 0),
|
||||
},
|
||||
]
|
||||
];
|
||||
|
@ -209,7 +209,9 @@ export const Calendar: any = observer((props: any) => {
|
||||
<BigCalendar
|
||||
popup
|
||||
selectable
|
||||
events={Array.isArray(field.value.slice()) ? field.value.slice() : []}
|
||||
events={
|
||||
Array.isArray(field.value.slice()) ? field.value.slice() : []
|
||||
}
|
||||
views={['month', 'week', 'day']}
|
||||
step={60}
|
||||
showMultiDayTimes
|
||||
|
@ -230,7 +230,7 @@ button.rbc-input::-moz-focus-inner {
|
||||
box-shadow: none;
|
||||
margin: 0;
|
||||
padding: 2px 5px;
|
||||
background-color: rgba(240, 240, 240, .65);
|
||||
background-color: rgba(240, 240, 240, 0.65);
|
||||
border-radius: 2px;
|
||||
// color: #1890ff;
|
||||
cursor: pointer;
|
||||
|
@ -128,6 +128,10 @@ const loadChinaRegionData = (
|
||||
|
||||
export default () => {
|
||||
return (
|
||||
<SchemaRenderer debug scope={{ loadChinaRegions, loadChinaRegionData }} schema={schema} />
|
||||
<SchemaRenderer
|
||||
debug
|
||||
scope={{ loadChinaRegions, loadChinaRegionData }}
|
||||
schema={schema}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
@ -7,7 +7,10 @@ export type ReactG2PlotProps<O> = {
|
||||
readonly config: O;
|
||||
};
|
||||
|
||||
export default forwardRef(function<O = any>(props: ReactG2PlotProps<O>, ref: any) {
|
||||
export default forwardRef(function <O = any>(
|
||||
props: ReactG2PlotProps<O>,
|
||||
ref: any,
|
||||
) {
|
||||
const { className, plot, config } = props;
|
||||
|
||||
const containerRef = useRef(undefined);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from 'react'
|
||||
import { connect, mapProps, mapReadPretty } from '@formily/react'
|
||||
import { Tag, Select } from 'antd'
|
||||
import { LoadingOutlined } from '@ant-design/icons'
|
||||
import React from 'react';
|
||||
import { connect, mapProps, mapReadPretty } from '@formily/react';
|
||||
import { Tag, Select } from 'antd';
|
||||
import { LoadingOutlined } from '@ant-design/icons';
|
||||
|
||||
const colors = {
|
||||
red: '薄暮',
|
||||
@ -22,13 +22,13 @@ export const ColorSelect = connect(
|
||||
(props) => {
|
||||
return (
|
||||
<Select {...props}>
|
||||
{Object.keys(colors).map(color => (
|
||||
{Object.keys(colors).map((color) => (
|
||||
<Select.Option value={color}>
|
||||
<Tag color={color}>{colors[color]}</Tag>
|
||||
</Select.Option>
|
||||
))}
|
||||
</Select>
|
||||
)
|
||||
);
|
||||
},
|
||||
mapProps((props, field) => {
|
||||
return {
|
||||
@ -42,17 +42,15 @@ export const ColorSelect = connect(
|
||||
)}
|
||||
</span>
|
||||
),
|
||||
}
|
||||
};
|
||||
}),
|
||||
mapReadPretty((props) => {
|
||||
const { value } = props;
|
||||
if (!colors[value]) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<Tag color={value}>{colors[value]}</Tag>
|
||||
return <Tag color={value}>{colors[value]}</Tag>;
|
||||
}),
|
||||
);
|
||||
})
|
||||
)
|
||||
|
||||
export default ColorSelect
|
||||
export default ColorSelect;
|
||||
|
@ -40,5 +40,5 @@ export default observer(() => {
|
||||
<div>
|
||||
<SchemaRenderer form={form} schema={schema} />
|
||||
</div>
|
||||
)
|
||||
})
|
||||
);
|
||||
});
|
||||
|
@ -16,7 +16,7 @@ const schema: ISchema = {
|
||||
{
|
||||
name: 'test2',
|
||||
title: '数据表 2',
|
||||
}
|
||||
},
|
||||
],
|
||||
properties: {
|
||||
title: {
|
||||
@ -31,7 +31,7 @@ const schema: ISchema = {
|
||||
title: '数据表标识',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'Input',
|
||||
"x-read-pretty": true,
|
||||
'x-read-pretty': true,
|
||||
},
|
||||
fields: {
|
||||
type: 'array',
|
||||
@ -39,8 +39,8 @@ const schema: ISchema = {
|
||||
'x-decorator': 'FormItem',
|
||||
'x-component': 'DatabaseField',
|
||||
default: [],
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const form = createForm();
|
||||
|
@ -42,10 +42,7 @@ import Modal from 'antd/lib/modal/Modal';
|
||||
import { clone, cloneDeep, get } from 'lodash';
|
||||
import { useEffect } from 'react';
|
||||
import { useRequest } from 'ahooks';
|
||||
import {
|
||||
createOrUpdateCollection,
|
||||
deleteCollection,
|
||||
} from '..';
|
||||
import { createOrUpdateCollection, deleteCollection } from '..';
|
||||
import { useCollectionsContext } from '../../constate/Collections';
|
||||
import {
|
||||
DragHandle,
|
||||
@ -185,7 +182,11 @@ export const DatabaseCollection = observer((props) => {
|
||||
<Input.Search
|
||||
size={'middle'}
|
||||
placeholder={'填写数据表名称'}
|
||||
enterButton={<><PlusOutlined /> 创建</>}
|
||||
enterButton={
|
||||
<>
|
||||
<PlusOutlined /> 创建
|
||||
</>
|
||||
}
|
||||
value={newValue}
|
||||
onChange={(e) => {
|
||||
setNewValue(e.target.value);
|
||||
|
@ -21,14 +21,14 @@ const groupLabels = {};
|
||||
|
||||
export function getDefaultFields() {
|
||||
const defaults = ['createdAt', 'updatedAt', 'createdBy', 'updatedBy'];
|
||||
return defaults.map(key => {
|
||||
return defaults.map((key) => {
|
||||
return {
|
||||
interface: key,
|
||||
key: uid(),
|
||||
name: uid(),
|
||||
privilege: 'undelete',
|
||||
...cloneDeep(interfaces.get(key)?.default),
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@ -55,19 +55,21 @@ registerGroupLabel('relation', '关系类型');
|
||||
registerGroupLabel('systemInfo', '系统信息');
|
||||
registerGroupLabel('others', '其他类型');
|
||||
|
||||
export const options = Object.keys(groupLabels).map(groupName => {
|
||||
export const options = Object.keys(groupLabels).map((groupName) => {
|
||||
return {
|
||||
label: groupLabels[groupName],
|
||||
children: Object.keys(fields[groupName] || {}).map((type) => {
|
||||
children: Object.keys(fields[groupName] || {})
|
||||
.map((type) => {
|
||||
return {
|
||||
name: type,
|
||||
...fields[groupName][type],
|
||||
};
|
||||
}).sort((a, b) => a.order - b.order),
|
||||
}
|
||||
})
|
||||
.sort((a, b) => a.order - b.order),
|
||||
};
|
||||
});
|
||||
|
||||
export const isAssociation = (field) => {
|
||||
const options = interfaces.get(field.interface);
|
||||
return options?.isAssociation;
|
||||
}
|
||||
};
|
||||
|
@ -40,7 +40,7 @@ export const percent: FieldOptions = {
|
||||
{ value: '0.001', label: '1.000' },
|
||||
{ value: '0.0001', label: '1.0000' },
|
||||
{ value: '0.00001', label: '1.00000' },
|
||||
]
|
||||
],
|
||||
},
|
||||
},
|
||||
operations: number.operations,
|
||||
|
@ -17,7 +17,7 @@ export const phone: FieldOptions = {
|
||||
// title,
|
||||
'x-component': 'Input',
|
||||
'x-decorator': 'FormItem',
|
||||
"x-validator": 'phone',
|
||||
'x-validator': 'phone',
|
||||
'x-designable-bar': 'Input.DesignableBar',
|
||||
},
|
||||
},
|
||||
|
@ -34,13 +34,17 @@ export const select: FieldOptions = {
|
||||
{
|
||||
label: '包含',
|
||||
value: 'in',
|
||||
schema: { 'x-component': 'Select', 'x-component-props': { mode: 'tags' } },
|
||||
schema: {
|
||||
'x-component': 'Select',
|
||||
'x-component-props': { mode: 'tags' },
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '不包含',
|
||||
value: 'notIn',
|
||||
schema: {
|
||||
'x-component': 'Select', 'x-component-props': { mode: 'tags' },
|
||||
'x-component': 'Select',
|
||||
'x-component-props': { mode: 'tags' },
|
||||
},
|
||||
},
|
||||
{ label: '非空', value: '$notNull', noValue: true },
|
||||
|
@ -33,7 +33,7 @@ export const subTable: FieldOptions = {
|
||||
},
|
||||
properties: {
|
||||
...defaultProps,
|
||||
'children': {
|
||||
children: {
|
||||
type: 'array',
|
||||
title: '子表格字段',
|
||||
'x-decorator': 'FormItem',
|
||||
|
@ -1,66 +1,72 @@
|
||||
import moment from 'moment'
|
||||
import { connect, mapProps, mapReadPretty, useField, useFieldSchema } from '@formily/react'
|
||||
import { DatePicker as AntdDatePicker } from 'antd'
|
||||
import moment from 'moment';
|
||||
import {
|
||||
connect,
|
||||
mapProps,
|
||||
mapReadPretty,
|
||||
useField,
|
||||
useFieldSchema,
|
||||
} from '@formily/react';
|
||||
import { DatePicker as AntdDatePicker } from 'antd';
|
||||
import {
|
||||
DatePickerProps as AntdDatePickerProps,
|
||||
RangePickerProps,
|
||||
} from 'antd/lib/date-picker'
|
||||
import { Display } from '../display'
|
||||
import { formatMomentValue, momentable } from '@formily/antd/esm/__builtins__'
|
||||
} from 'antd/lib/date-picker';
|
||||
import { Display } from '../display';
|
||||
import { formatMomentValue, momentable } from '@formily/antd/esm/__builtins__';
|
||||
|
||||
type DatePickerProps<PickerProps> = Exclude<
|
||||
PickerProps,
|
||||
'value' | 'onChange'
|
||||
> & {
|
||||
value: string
|
||||
onChange: (value: string | string[]) => void
|
||||
}
|
||||
value: string;
|
||||
onChange: (value: string | string[]) => void;
|
||||
};
|
||||
|
||||
type ComposedDatePicker = React.FC<AntdDatePickerProps> & {
|
||||
RangePicker?: React.FC<RangePickerProps>
|
||||
}
|
||||
RangePicker?: React.FC<RangePickerProps>;
|
||||
};
|
||||
|
||||
const mapDateFormat = function () {
|
||||
const getDefaultFormat = (props: DatePickerProps<AntdDatePickerProps>) => {
|
||||
if (props['picker'] === 'month') {
|
||||
return 'YYYY-MM'
|
||||
return 'YYYY-MM';
|
||||
} else if (props['picker'] === 'quarter') {
|
||||
return 'YYYY-\\QQ'
|
||||
return 'YYYY-\\QQ';
|
||||
} else if (props['picker'] === 'year') {
|
||||
return 'YYYY'
|
||||
return 'YYYY';
|
||||
} else if (props['picker'] === 'week') {
|
||||
return 'YYYY-wo'
|
||||
}
|
||||
return props['showTime'] ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD'
|
||||
return 'YYYY-wo';
|
||||
}
|
||||
return props['showTime'] ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD';
|
||||
};
|
||||
return (props: any) => {
|
||||
const field = useField();
|
||||
const fieldSchema = useFieldSchema();
|
||||
const format = props['format'] || getDefaultFormat(props)
|
||||
const onChange = props.onChange
|
||||
const format = props['format'] || getDefaultFormat(props);
|
||||
const onChange = props.onChange;
|
||||
return {
|
||||
...props,
|
||||
format: format,
|
||||
value: momentable(props.value, format === 'YYYY-wo' ? 'YYYY-w' : format),
|
||||
onChange: (value: moment.Moment | moment.Moment[]) => {
|
||||
if (onChange) {
|
||||
onChange(formatMomentValue(value, format))
|
||||
onChange(formatMomentValue(value, format));
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
export const DatePicker: ComposedDatePicker = connect(
|
||||
AntdDatePicker,
|
||||
mapProps(mapDateFormat()),
|
||||
mapReadPretty(Display.DatePicker)
|
||||
)
|
||||
mapReadPretty(Display.DatePicker),
|
||||
);
|
||||
|
||||
DatePicker.RangePicker = connect(
|
||||
AntdDatePicker.RangePicker,
|
||||
mapProps(mapDateFormat()),
|
||||
mapReadPretty(Display.DateRangePicker)
|
||||
)
|
||||
mapReadPretty(Display.DateRangePicker),
|
||||
);
|
||||
|
||||
export default DatePicker
|
||||
export default DatePicker;
|
||||
|
@ -1,16 +1,13 @@
|
||||
|
||||
import React from 'react';
|
||||
import { observer, useFieldSchema } from '@formily/react';
|
||||
import {
|
||||
DragDropManagerProvider,
|
||||
} from './../../components/drag-and-drop';
|
||||
import { DragDropManagerProvider } from './../../components/drag-and-drop';
|
||||
|
||||
export const DragAndDrop = observer((props) => {
|
||||
const schema = useFieldSchema();
|
||||
console.log('DragAndDrop')
|
||||
console.log('DragAndDrop');
|
||||
return (
|
||||
<DragDropManagerProvider uid={schema.name}>
|
||||
<div className={'nb-dnd'}>{props.children}</div>
|
||||
</DragDropManagerProvider>
|
||||
)
|
||||
);
|
||||
});
|
||||
|
@ -171,7 +171,9 @@ export const FilterItem = (props) => {
|
||||
[],
|
||||
);
|
||||
|
||||
const columnEnum: any = [...columns.values()].map((column) => column.toJSON());
|
||||
const columnEnum: any = [...columns.values()].map((column) =>
|
||||
column.toJSON(),
|
||||
);
|
||||
|
||||
return (
|
||||
<FormProvider form={form}>
|
||||
|
@ -14,7 +14,7 @@ const schema: ISchema = {
|
||||
type: 'void',
|
||||
name: uid(),
|
||||
'x-component': 'Grid',
|
||||
"x-component-props": {
|
||||
'x-component-props': {
|
||||
addNewComponent: 'AddNew.CardItem',
|
||||
},
|
||||
properties: {
|
||||
@ -186,7 +186,5 @@ const schema: ISchema = {
|
||||
};
|
||||
|
||||
export default () => {
|
||||
return (
|
||||
<SchemaRenderer components={{ Grid }} schema={schema} />
|
||||
);
|
||||
return <SchemaRenderer components={{ Grid }} schema={schema} />;
|
||||
};
|
||||
|
@ -101,7 +101,7 @@ body.dragging {
|
||||
.nb-block-item {
|
||||
position: relative;
|
||||
&.isDragging {
|
||||
opacity: .3;
|
||||
opacity: 0.3;
|
||||
}
|
||||
&.isOver::after {
|
||||
content: '';
|
||||
|
@ -1,10 +1,15 @@
|
||||
import React from 'react';
|
||||
import { ISchema as IFormilySchema, observer, Schema, useField } from '@formily/react';
|
||||
import {
|
||||
ISchema as IFormilySchema,
|
||||
observer,
|
||||
Schema,
|
||||
useField,
|
||||
} from '@formily/react';
|
||||
import { extend } from 'umi-request';
|
||||
|
||||
import './designable-bar/style.less';
|
||||
|
||||
export type FormilyISchema = IFormilySchema
|
||||
export type FormilyISchema = IFormilySchema;
|
||||
|
||||
export interface ISchema extends IFormilySchema {
|
||||
[key: string]: any;
|
||||
|
@ -1,7 +1,14 @@
|
||||
import React from 'react'
|
||||
import { connect, mapProps, mapReadPretty, observer, useField, useFieldSchema } from '@formily/react'
|
||||
import { Input as AntdInput } from 'antd'
|
||||
import { InputProps, TextAreaProps } from 'antd/lib/input'
|
||||
import React from 'react';
|
||||
import {
|
||||
connect,
|
||||
mapProps,
|
||||
mapReadPretty,
|
||||
observer,
|
||||
useField,
|
||||
useFieldSchema,
|
||||
} from '@formily/react';
|
||||
import { Input as AntdInput } from 'antd';
|
||||
import { InputProps, TextAreaProps } from 'antd/lib/input';
|
||||
import { Display } from '../display';
|
||||
import { DesignableBar } from './DesignableBar';
|
||||
import { Dropdown, Menu, Space } from 'antd';
|
||||
@ -17,10 +24,10 @@ import { isGridRowOrCol } from '../grid';
|
||||
import { DragHandle } from '../../components/Sortable';
|
||||
|
||||
type ComposedInput = React.FC<InputProps> & {
|
||||
TextArea?: React.FC<TextAreaProps>
|
||||
URL?: React.FC<InputProps>
|
||||
DesignableBar?: React.FC<any>
|
||||
}
|
||||
TextArea?: React.FC<TextAreaProps>;
|
||||
URL?: React.FC<InputProps>;
|
||||
DesignableBar?: React.FC<any>;
|
||||
};
|
||||
|
||||
export const Input: ComposedInput = connect(
|
||||
AntdInput,
|
||||
@ -36,12 +43,12 @@ export const Input: ComposedInput = connect(
|
||||
)}
|
||||
</span>
|
||||
),
|
||||
}
|
||||
};
|
||||
}),
|
||||
mapReadPretty(Display.Input)
|
||||
)
|
||||
mapReadPretty(Display.Input),
|
||||
);
|
||||
|
||||
Input.TextArea = connect(AntdInput.TextArea, mapReadPretty(Display.TextArea))
|
||||
Input.URL = connect(AntdInput, mapReadPretty(Display.URL))
|
||||
Input.TextArea = connect(AntdInput.TextArea, mapReadPretty(Display.TextArea));
|
||||
Input.URL = connect(AntdInput, mapReadPretty(Display.URL));
|
||||
|
||||
export default Input
|
||||
export default Input;
|
||||
|
@ -11,12 +11,7 @@ import {
|
||||
useForm,
|
||||
RecursionField,
|
||||
} from '@formily/react';
|
||||
import {
|
||||
useSchemaPath,
|
||||
SchemaField,
|
||||
useDesignable,
|
||||
ISchema,
|
||||
} from '../';
|
||||
import { useSchemaPath, SchemaField, useDesignable, ISchema } from '../';
|
||||
import get from 'lodash/get';
|
||||
import { Button, Dropdown, Menu, Space } from 'antd';
|
||||
import { MenuOutlined, DragOutlined } from '@ant-design/icons';
|
||||
|
@ -208,5 +208,11 @@ const schema: ISchema = {
|
||||
};
|
||||
|
||||
export default () => {
|
||||
return <SchemaRenderer scope={{ Kanban }} components={{ Kanban }} schema={schema} />;
|
||||
return (
|
||||
<SchemaRenderer
|
||||
scope={{ Kanban }}
|
||||
components={{ Kanban }}
|
||||
schema={schema}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
@ -29,7 +29,11 @@ import { useState } from 'react';
|
||||
import { CSS } from '@dnd-kit/utilities';
|
||||
import cls from 'classnames';
|
||||
import './style.less';
|
||||
import { CollectionProvider, useCollectionContext, useResourceRequest } from '../../constate';
|
||||
import {
|
||||
CollectionProvider,
|
||||
useCollectionContext,
|
||||
useResourceRequest,
|
||||
} from '../../constate';
|
||||
import { Resource } from '../../resource';
|
||||
import { useRequest } from 'ahooks';
|
||||
import { Action } from '../action';
|
||||
|
@ -26,7 +26,7 @@
|
||||
.nb-kanban-item {
|
||||
margin-bottom: 12px;
|
||||
&.isDragging {
|
||||
opacity: .2;
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
.ant-formily-item-control-content-component {
|
||||
@ -51,7 +51,8 @@
|
||||
.nb-kanban-drag-overlay {
|
||||
.isDragging {
|
||||
opacity: 1 !important;
|
||||
box-shadow: 0 1px 2px -2px rgb(0 0 0 / 16%), 0 3px 6px 0 rgb(0 0 0 / 12%), 0 5px 12px 4px rgb(0 0 0 / 9%);
|
||||
box-shadow: 0 1px 2px -2px rgb(0 0 0 / 16%), 0 3px 6px 0 rgb(0 0 0 / 12%),
|
||||
0 5px 12px 4px rgb(0 0 0 / 9%);
|
||||
}
|
||||
.designable-bar {
|
||||
display: none !important;
|
||||
@ -69,7 +70,8 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.nb-grid-block, .ant-formily-item {
|
||||
.nb-grid-block,
|
||||
.ant-formily-item {
|
||||
margin-bottom: 12px !important;
|
||||
}
|
||||
|
||||
@ -132,7 +134,8 @@
|
||||
.ant-upload-list-picture-card .ant-upload-list-item-name {
|
||||
display: none;
|
||||
}
|
||||
.ant-upload-list-picture .ant-upload-list-item, .ant-upload-list-picture-card .ant-upload-list-item {
|
||||
.ant-upload-list-picture .ant-upload-list-item,
|
||||
.ant-upload-list-picture-card .ant-upload-list-item {
|
||||
padding: 1px;
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ const schema: ISchema = {
|
||||
title: `链接`,
|
||||
'x-designable-bar': 'Menu.DesignableBar',
|
||||
'x-component': 'Menu.Link',
|
||||
"x-component-props": {
|
||||
'x-component-props': {
|
||||
to: '/abc/def',
|
||||
},
|
||||
},
|
||||
|
@ -86,11 +86,7 @@ export default () => {
|
||||
return (
|
||||
<Layout>
|
||||
<Layout.Header>
|
||||
<SchemaRenderer
|
||||
debug={true}
|
||||
scope={{ sideMenuRef }}
|
||||
schema={schema}
|
||||
/>
|
||||
<SchemaRenderer debug={true} scope={{ sideMenuRef }} schema={schema} />
|
||||
</Layout.Header>
|
||||
<Layout>
|
||||
<Layout.Sider theme={'light'} ref={sideMenuRef}></Layout.Sider>
|
||||
|
@ -126,7 +126,7 @@
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: #f18b62;
|
||||
opacity: .5;
|
||||
opacity: 0.5;
|
||||
}
|
||||
.droppable:not(.isDragging).isOver::after {
|
||||
content: '';
|
||||
@ -151,7 +151,7 @@
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: #f18b62;
|
||||
opacity: .3;
|
||||
opacity: 0.3;
|
||||
}
|
||||
.droppable:not(.isDragging).isOver::after {
|
||||
content: '';
|
||||
|
@ -13,9 +13,7 @@ export const Page = observer((props) => {
|
||||
<title>{documentTitle}</title>
|
||||
</Helmet>
|
||||
<AntdPageHeader ghost={false} title={pageTitle} {...others} />
|
||||
<div style={{margin: 24}}>
|
||||
{children}
|
||||
</div>
|
||||
<div style={{ margin: 24 }}>{children}</div>
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
@ -1,164 +1,164 @@
|
||||
import React, { Fragment } from 'react'
|
||||
import { isFn } from '@formily/shared'
|
||||
import React, { Fragment } from 'react';
|
||||
import { isFn } from '@formily/shared';
|
||||
|
||||
type ReactRenderPropsChildren<T = any> =
|
||||
| React.ReactNode
|
||||
| ((props: T) => React.ReactElement)
|
||||
| ((props: T) => React.ReactElement);
|
||||
|
||||
interface IPasswordStrengthProps {
|
||||
value?: React.ReactText
|
||||
children?: ReactRenderPropsChildren<number>
|
||||
value?: React.ReactText;
|
||||
children?: ReactRenderPropsChildren<number>;
|
||||
}
|
||||
|
||||
const isNum = function (c) {
|
||||
return c >= 48 && c <= 57
|
||||
}
|
||||
return c >= 48 && c <= 57;
|
||||
};
|
||||
const isLower = function (c) {
|
||||
return c >= 97 && c <= 122
|
||||
}
|
||||
return c >= 97 && c <= 122;
|
||||
};
|
||||
const isUpper = function (c) {
|
||||
return c >= 65 && c <= 90
|
||||
}
|
||||
return c >= 65 && c <= 90;
|
||||
};
|
||||
const isSymbol = function (c) {
|
||||
return !(isLower(c) || isUpper(c) || isNum(c))
|
||||
}
|
||||
return !(isLower(c) || isUpper(c) || isNum(c));
|
||||
};
|
||||
const isLetter = function (c) {
|
||||
return isLower(c) || isUpper(c)
|
||||
}
|
||||
return isLower(c) || isUpper(c);
|
||||
};
|
||||
|
||||
const getStrength = (val) => {
|
||||
if (!val) return 0
|
||||
let num = 0
|
||||
let lower = 0
|
||||
let upper = 0
|
||||
let symbol = 0
|
||||
let MNS = 0
|
||||
let rep = 0
|
||||
let repC = 0
|
||||
let consecutive = 0
|
||||
let sequential = 0
|
||||
const len = () => num + lower + upper + symbol
|
||||
if (!val) return 0;
|
||||
let num = 0;
|
||||
let lower = 0;
|
||||
let upper = 0;
|
||||
let symbol = 0;
|
||||
let MNS = 0;
|
||||
let rep = 0;
|
||||
let repC = 0;
|
||||
let consecutive = 0;
|
||||
let sequential = 0;
|
||||
const len = () => num + lower + upper + symbol;
|
||||
const callme = () => {
|
||||
let re = num > 0 ? 1 : 0
|
||||
re += lower > 0 ? 1 : 0
|
||||
re += upper > 0 ? 1 : 0
|
||||
re += symbol > 0 ? 1 : 0
|
||||
let re = num > 0 ? 1 : 0;
|
||||
re += lower > 0 ? 1 : 0;
|
||||
re += upper > 0 ? 1 : 0;
|
||||
re += symbol > 0 ? 1 : 0;
|
||||
if (re > 2 && len() >= 8) {
|
||||
return re + 1
|
||||
return re + 1;
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
for (let i = 0; i < val.length; i++) {
|
||||
const c = val.charCodeAt(i)
|
||||
const c = val.charCodeAt(i);
|
||||
if (isNum(c)) {
|
||||
num++
|
||||
num++;
|
||||
if (i !== 0 && i !== val.length - 1) {
|
||||
MNS++
|
||||
MNS++;
|
||||
}
|
||||
if (i > 0 && isNum(val.charCodeAt(i - 1))) {
|
||||
consecutive++
|
||||
consecutive++;
|
||||
}
|
||||
} else if (isLower(c)) {
|
||||
lower++
|
||||
lower++;
|
||||
if (i > 0 && isLower(val.charCodeAt(i - 1))) {
|
||||
consecutive++
|
||||
consecutive++;
|
||||
}
|
||||
} else if (isUpper(c)) {
|
||||
upper++
|
||||
upper++;
|
||||
if (i > 0 && isUpper(val.charCodeAt(i - 1))) {
|
||||
consecutive++
|
||||
consecutive++;
|
||||
}
|
||||
} else {
|
||||
symbol++
|
||||
symbol++;
|
||||
if (i !== 0 && i !== val.length - 1) {
|
||||
MNS++
|
||||
MNS++;
|
||||
}
|
||||
}
|
||||
let exists = false
|
||||
let exists = false;
|
||||
for (let j = 0; j < val.length; j++) {
|
||||
if (val[i] === val[j] && i !== j) {
|
||||
exists = true
|
||||
repC += Math.abs(val.length / (j - i))
|
||||
exists = true;
|
||||
repC += Math.abs(val.length / (j - i));
|
||||
}
|
||||
}
|
||||
if (exists) {
|
||||
rep++
|
||||
const unique = val.length - rep
|
||||
repC = unique ? Math.ceil(repC / unique) : Math.ceil(repC)
|
||||
rep++;
|
||||
const unique = val.length - rep;
|
||||
repC = unique ? Math.ceil(repC / unique) : Math.ceil(repC);
|
||||
}
|
||||
if (i > 1) {
|
||||
const last1 = val.charCodeAt(i - 1)
|
||||
const last2 = val.charCodeAt(i - 2)
|
||||
const last1 = val.charCodeAt(i - 1);
|
||||
const last2 = val.charCodeAt(i - 2);
|
||||
if (isLetter(c)) {
|
||||
if (isLetter(last1) && isLetter(last2)) {
|
||||
const v = val.toLowerCase()
|
||||
const vi = v.charCodeAt(i)
|
||||
const vi1 = v.charCodeAt(i - 1)
|
||||
const vi2 = v.charCodeAt(i - 2)
|
||||
const v = val.toLowerCase();
|
||||
const vi = v.charCodeAt(i);
|
||||
const vi1 = v.charCodeAt(i - 1);
|
||||
const vi2 = v.charCodeAt(i - 2);
|
||||
if (vi - vi1 === vi1 - vi2 && Math.abs(vi - vi1) === 1) {
|
||||
sequential++
|
||||
sequential++;
|
||||
}
|
||||
}
|
||||
} else if (isNum(c)) {
|
||||
if (isNum(last1) && isNum(last2)) {
|
||||
if (c - last1 === last1 - last2 && Math.abs(c - last1) === 1) {
|
||||
sequential++
|
||||
sequential++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (isSymbol(last1) && isSymbol(last2)) {
|
||||
if (c - last1 === last1 - last2 && Math.abs(c - last1) === 1) {
|
||||
sequential++
|
||||
sequential++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let sum = 0
|
||||
const length = len()
|
||||
sum += 4 * length
|
||||
let sum = 0;
|
||||
const length = len();
|
||||
sum += 4 * length;
|
||||
if (lower > 0) {
|
||||
sum += 2 * (length - lower)
|
||||
sum += 2 * (length - lower);
|
||||
}
|
||||
if (upper > 0) {
|
||||
sum += 2 * (length - upper)
|
||||
sum += 2 * (length - upper);
|
||||
}
|
||||
if (num !== length) {
|
||||
sum += 4 * num
|
||||
sum += 4 * num;
|
||||
}
|
||||
sum += 6 * symbol
|
||||
sum += 2 * MNS
|
||||
sum += 2 * callme()
|
||||
sum += 6 * symbol;
|
||||
sum += 2 * MNS;
|
||||
sum += 2 * callme();
|
||||
if (length === lower + upper) {
|
||||
sum -= length
|
||||
sum -= length;
|
||||
}
|
||||
if (length === num) {
|
||||
sum -= num
|
||||
sum -= num;
|
||||
}
|
||||
sum -= repC
|
||||
sum -= 2 * consecutive
|
||||
sum -= 3 * sequential
|
||||
sum = sum < 0 ? 0 : sum
|
||||
sum = sum > 100 ? 100 : sum
|
||||
sum -= repC;
|
||||
sum -= 2 * consecutive;
|
||||
sum -= 3 * sequential;
|
||||
sum = sum < 0 ? 0 : sum;
|
||||
sum = sum > 100 ? 100 : sum;
|
||||
|
||||
if (sum >= 80) {
|
||||
return 100
|
||||
return 100;
|
||||
} else if (sum >= 60) {
|
||||
return 80
|
||||
return 80;
|
||||
} else if (sum >= 40) {
|
||||
return 60
|
||||
return 60;
|
||||
} else if (sum >= 20) {
|
||||
return 40
|
||||
return 40;
|
||||
} else {
|
||||
return 20
|
||||
}
|
||||
return 20;
|
||||
}
|
||||
};
|
||||
|
||||
export const PasswordStrength: React.FC<IPasswordStrengthProps> = (props) => {
|
||||
if (isFn(props.children)) {
|
||||
return props.children(getStrength(String(props.value)))
|
||||
return props.children(getStrength(String(props.value)));
|
||||
} else {
|
||||
return <Fragment>{props.children}</Fragment>
|
||||
}
|
||||
return <Fragment>{props.children}</Fragment>;
|
||||
}
|
||||
};
|
||||
|
@ -1,23 +1,29 @@
|
||||
import React from 'react';
|
||||
import { connect, mapProps, mapReadPretty, SchemaOptionsContext, useField } from '@formily/react'
|
||||
import { Radio as AntdRadio, Tag } from 'antd'
|
||||
import { RadioProps, RadioGroupProps } from 'antd/lib/radio'
|
||||
import {
|
||||
connect,
|
||||
mapProps,
|
||||
mapReadPretty,
|
||||
SchemaOptionsContext,
|
||||
useField,
|
||||
} from '@formily/react';
|
||||
import { Radio as AntdRadio, Tag } from 'antd';
|
||||
import { RadioProps, RadioGroupProps } from 'antd/lib/radio';
|
||||
import { isValid } from '@formily/shared';
|
||||
|
||||
type ComposedRadio = React.FC<RadioProps> & {
|
||||
Group?: React.FC<RadioGroupProps>
|
||||
__ANT_RADIO?: boolean
|
||||
}
|
||||
Group?: React.FC<RadioGroupProps>;
|
||||
__ANT_RADIO?: boolean;
|
||||
};
|
||||
|
||||
export const Radio: ComposedRadio = connect(
|
||||
AntdRadio,
|
||||
mapProps({
|
||||
value: 'checked',
|
||||
onInput: 'onChange',
|
||||
})
|
||||
)
|
||||
}),
|
||||
);
|
||||
|
||||
Radio.__ANT_RADIO = true
|
||||
Radio.__ANT_RADIO = true;
|
||||
|
||||
Radio.Group = connect(
|
||||
AntdRadio.Group,
|
||||
@ -31,17 +37,19 @@ Radio.Group = connect(
|
||||
const { options = [], value } = props;
|
||||
const field = useField<any>();
|
||||
const dataSource = field.dataSource || [];
|
||||
console.log({dataSource})
|
||||
console.log({ dataSource });
|
||||
return (
|
||||
<div>
|
||||
{dataSource
|
||||
.filter((option) => option.value === value)
|
||||
.map((option, key) => (
|
||||
<Tag key={key} color={option.color}>{option.label}</Tag>
|
||||
<Tag key={key} color={option.color}>
|
||||
{option.label}
|
||||
</Tag>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}),
|
||||
)
|
||||
);
|
||||
|
||||
export default Radio
|
||||
export default Radio;
|
||||
|
@ -25,7 +25,11 @@ import { BlockSchemaContext, VisibleContext } from '../../context';
|
||||
import { SchemaRenderer } from '../../components/schema-renderer';
|
||||
import { uid } from '@formily/shared';
|
||||
import { CollectionFieldContext } from '../table';
|
||||
import { CollectionProvider, useCollectionContext, useResourceRequest } from '../../constate';
|
||||
import {
|
||||
CollectionProvider,
|
||||
useCollectionContext,
|
||||
useResourceRequest,
|
||||
} from '../../constate';
|
||||
import { Resource } from '../../resource';
|
||||
import { useRequest } from 'ahooks';
|
||||
import constate from 'constate';
|
||||
@ -267,11 +271,13 @@ Select.useSelect = () => {
|
||||
|
||||
export const useSelectedRowKeys = () => {
|
||||
const { selectedRows } = useContext(SelectedRowsContext);
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState<any>(selectedRows.map((row) => row.id));
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState<any>(
|
||||
selectedRows.map((row) => row.id),
|
||||
);
|
||||
useEffect(() => {
|
||||
setSelectedRowKeys(selectedRows.map((row) => row.id));
|
||||
}, [selectedRows]);
|
||||
console.log('useSelectedRowKeys', selectedRows)
|
||||
console.log('useSelectedRowKeys', selectedRows);
|
||||
return { selectedRowKeys, setSelectedRowKeys };
|
||||
};
|
||||
|
||||
@ -322,7 +328,7 @@ Select.Drawer = connect(
|
||||
};
|
||||
}
|
||||
const [selectedRows, setSelectedRows] = useState(toArr(field.value));
|
||||
console.log('useSelectedRowKeys.toArr', toArr(field.value))
|
||||
console.log('useSelectedRowKeys.toArr', toArr(field.value));
|
||||
useEffect(() => {
|
||||
setSelectedRows(toArr(field.value));
|
||||
}, [field.value]);
|
||||
|
@ -11,11 +11,7 @@ import { cloneDeep, cloneDeepWith, findIndex, forIn, range, set } from 'lodash';
|
||||
import React, { Fragment, useEffect, useState } from 'react';
|
||||
import { useContext } from 'react';
|
||||
import { createContext } from 'react';
|
||||
import {
|
||||
useDesignable,
|
||||
createCollectionField,
|
||||
ISchema,
|
||||
} from '..';
|
||||
import { useDesignable, createCollectionField, ISchema } from '..';
|
||||
import { uid, merge } from '@formily/shared';
|
||||
import useRequest from '@ahooksjs/use-request';
|
||||
import { BaseResult } from '@ahooksjs/use-request/lib/types';
|
||||
|
@ -186,13 +186,14 @@ td.nb-table-operation {
|
||||
.ant-formily-item-feedback-layout-popover {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.ant-formily-item-control .ant-formily-item-control-content .ant-formily-item-control-content-component {
|
||||
.ant-formily-item-control
|
||||
.ant-formily-item-control-content
|
||||
.ant-formily-item-control-content-component {
|
||||
min-height: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.ant-dropdown-menu-item {
|
||||
&:hover {
|
||||
.designable-bar {
|
||||
@ -238,7 +239,6 @@ td.nb-table-operation {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
|
||||
.field-interface-attachment {
|
||||
margin-top: -13px;
|
||||
margin-bottom: -13px;
|
||||
@ -253,7 +253,7 @@ td.nb-table-operation {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: #f18b62;
|
||||
opacity: .3;
|
||||
opacity: 0.3;
|
||||
}
|
||||
&.droppable:not(.isDragging).isOver::after {
|
||||
content: '';
|
||||
@ -278,7 +278,7 @@ td.nb-table-operation {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: #f18b62;
|
||||
opacity: .3;
|
||||
opacity: 0.3;
|
||||
}
|
||||
.droppable:not(.isDragging).isOver::after {
|
||||
content: '';
|
||||
|
@ -39,7 +39,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.ant-tabs-tab:first-child {
|
||||
.nb-tab-pane {
|
||||
.designable-bar {
|
||||
@ -91,7 +90,7 @@
|
||||
height: 100%;
|
||||
left: -16px;
|
||||
background-color: #f18b62;
|
||||
opacity: .3;
|
||||
opacity: 0.3;
|
||||
}
|
||||
.droppable:not(.isDragging).isOver::after {
|
||||
content: '';
|
||||
|
@ -1,44 +1,44 @@
|
||||
import moment from 'moment'
|
||||
import { connect, mapProps, mapReadPretty } from '@formily/react'
|
||||
import { TimePicker as AntdTimePicker } from 'antd'
|
||||
import moment from 'moment';
|
||||
import { connect, mapProps, mapReadPretty } from '@formily/react';
|
||||
import { TimePicker as AntdTimePicker } from 'antd';
|
||||
import {
|
||||
TimePickerProps as AntdTimePickerProps,
|
||||
TimeRangePickerProps,
|
||||
} from 'antd/lib/time-picker'
|
||||
import { Display } from '../display'
|
||||
import { formatMomentValue, momentable } from '@formily/antd/esm/__builtins__'
|
||||
} from 'antd/lib/time-picker';
|
||||
import { Display } from '../display';
|
||||
import { formatMomentValue, momentable } from '@formily/antd/esm/__builtins__';
|
||||
|
||||
type ComposedTimePicker = React.FC<AntdTimePickerProps> & {
|
||||
RangePicker?: React.FC<TimeRangePickerProps>
|
||||
}
|
||||
RangePicker?: React.FC<TimeRangePickerProps>;
|
||||
};
|
||||
|
||||
const mapTimeFormat = function () {
|
||||
return (props: any) => {
|
||||
const format = props['format'] || 'HH:mm:ss'
|
||||
const onChange = props.onChange
|
||||
const format = props['format'] || 'HH:mm:ss';
|
||||
const onChange = props.onChange;
|
||||
return {
|
||||
...props,
|
||||
format,
|
||||
value: momentable(props.value, format),
|
||||
onChange: (value: moment.Moment | moment.Moment[]) => {
|
||||
if (onChange) {
|
||||
onChange(formatMomentValue(value, format))
|
||||
onChange(formatMomentValue(value, format));
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
export const TimePicker: ComposedTimePicker = connect(
|
||||
AntdTimePicker,
|
||||
mapProps(mapTimeFormat()),
|
||||
mapReadPretty(Display.TimePicker)
|
||||
)
|
||||
mapReadPretty(Display.TimePicker),
|
||||
);
|
||||
|
||||
TimePicker.RangePicker = connect(
|
||||
AntdTimePicker.RangePicker,
|
||||
mapProps(mapTimeFormat()),
|
||||
mapReadPretty(Display.TimeRangePicker)
|
||||
)
|
||||
mapReadPretty(Display.TimeRangePicker),
|
||||
);
|
||||
|
||||
export default TimePicker
|
||||
export default TimePicker;
|
||||
|
@ -1,8 +1,8 @@
|
||||
import React from 'react'
|
||||
import { connect, mapReadPretty, mapProps } from '@formily/react'
|
||||
import { TreeSelect as AntdTreeSelect } from 'antd'
|
||||
import { Display } from '../display'
|
||||
import { LoadingOutlined } from '@ant-design/icons'
|
||||
import React from 'react';
|
||||
import { connect, mapReadPretty, mapProps } from '@formily/react';
|
||||
import { TreeSelect as AntdTreeSelect } from 'antd';
|
||||
import { Display } from '../display';
|
||||
import { LoadingOutlined } from '@ant-design/icons';
|
||||
export const TreeSelect = connect(
|
||||
AntdTreeSelect,
|
||||
mapProps(
|
||||
@ -18,10 +18,10 @@ export const TreeSelect = connect(
|
||||
) : (
|
||||
props.suffixIcon
|
||||
),
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
),
|
||||
mapReadPretty(Display.TreeSelect)
|
||||
)
|
||||
mapReadPretty(Display.TreeSelect),
|
||||
);
|
||||
|
||||
export default TreeSelect
|
||||
export default TreeSelect;
|
||||
|
@ -49,7 +49,7 @@ const schema = {
|
||||
value: '{{$self.value}}',
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
],
|
||||
},
|
||||
read: {
|
||||
|
@ -1,62 +1,62 @@
|
||||
export const UPLOAD_PLACEHOLDER = [
|
||||
{
|
||||
ext: /\.docx?$/i,
|
||||
icon: '//img.alicdn.com/tfs/TB1n8jfr1uSBuNjy1XcXXcYjFXa-200-200.png'
|
||||
icon: '//img.alicdn.com/tfs/TB1n8jfr1uSBuNjy1XcXXcYjFXa-200-200.png',
|
||||
},
|
||||
{
|
||||
ext: /\.pptx?$/i,
|
||||
icon: '//img.alicdn.com/tfs/TB1ItgWr_tYBeNjy1XdXXXXyVXa-200-200.png'
|
||||
icon: '//img.alicdn.com/tfs/TB1ItgWr_tYBeNjy1XdXXXXyVXa-200-200.png',
|
||||
},
|
||||
{
|
||||
ext: /\.jpe?g$/i,
|
||||
icon: '//img.alicdn.com/tfs/TB1wrT5r9BYBeNjy0FeXXbnmFXa-200-200.png'
|
||||
icon: '//img.alicdn.com/tfs/TB1wrT5r9BYBeNjy0FeXXbnmFXa-200-200.png',
|
||||
},
|
||||
{
|
||||
ext: /\.pdf$/i,
|
||||
icon: '//img.alicdn.com/tfs/TB1GwD8r9BYBeNjy0FeXXbnmFXa-200-200.png'
|
||||
icon: '//img.alicdn.com/tfs/TB1GwD8r9BYBeNjy0FeXXbnmFXa-200-200.png',
|
||||
},
|
||||
{
|
||||
ext: /\.png$/i,
|
||||
icon: '//img.alicdn.com/tfs/TB1BHT5r9BYBeNjy0FeXXbnmFXa-200-200.png'
|
||||
icon: '//img.alicdn.com/tfs/TB1BHT5r9BYBeNjy0FeXXbnmFXa-200-200.png',
|
||||
},
|
||||
{
|
||||
ext: /\.eps$/i,
|
||||
icon: '//img.alicdn.com/tfs/TB1G_iGrVOWBuNjy0FiXXXFxVXa-200-200.png'
|
||||
icon: '//img.alicdn.com/tfs/TB1G_iGrVOWBuNjy0FiXXXFxVXa-200-200.png',
|
||||
},
|
||||
{
|
||||
ext: /\.ai$/i,
|
||||
icon: '//img.alicdn.com/tfs/TB1B2cVr_tYBeNjy1XdXXXXyVXa-200-200.png'
|
||||
icon: '//img.alicdn.com/tfs/TB1B2cVr_tYBeNjy1XdXXXXyVXa-200-200.png',
|
||||
},
|
||||
{
|
||||
ext: /\.gif$/i,
|
||||
icon: '//img.alicdn.com/tfs/TB1DTiGrVOWBuNjy0FiXXXFxVXa-200-200.png'
|
||||
icon: '//img.alicdn.com/tfs/TB1DTiGrVOWBuNjy0FiXXXFxVXa-200-200.png',
|
||||
},
|
||||
{
|
||||
ext: /\.svg$/i,
|
||||
icon: '//img.alicdn.com/tfs/TB1uUm9rY9YBuNjy0FgXXcxcXXa-200-200.png'
|
||||
icon: '//img.alicdn.com/tfs/TB1uUm9rY9YBuNjy0FgXXcxcXXa-200-200.png',
|
||||
},
|
||||
{
|
||||
ext: /\.xlsx?$/i,
|
||||
icon: '//img.alicdn.com/tfs/TB1any1r1OSBuNjy0FdXXbDnVXa-200-200.png'
|
||||
icon: '//img.alicdn.com/tfs/TB1any1r1OSBuNjy0FdXXbDnVXa-200-200.png',
|
||||
},
|
||||
{
|
||||
ext: /\.psd?$/i,
|
||||
icon: '//img.alicdn.com/tfs/TB1_nu1r1OSBuNjy0FdXXbDnVXa-200-200.png'
|
||||
icon: '//img.alicdn.com/tfs/TB1_nu1r1OSBuNjy0FdXXbDnVXa-200-200.png',
|
||||
},
|
||||
{
|
||||
ext: /\.(wav|aif|aiff|au|mp1|mp2|mp3|ra|rm|ram|mid|rmi)$/i,
|
||||
icon: '//img.alicdn.com/tfs/TB1jPvwr49YBuNjy0FfXXXIsVXa-200-200.png'
|
||||
icon: '//img.alicdn.com/tfs/TB1jPvwr49YBuNjy0FfXXXIsVXa-200-200.png',
|
||||
},
|
||||
{
|
||||
ext: /\.(avi|wmv|mpg|mpeg|vob|dat|3gp|mp4|mkv|rm|rmvb|mov|flv)$/i,
|
||||
icon: '//img.alicdn.com/tfs/TB1FrT5r9BYBeNjy0FeXXbnmFXa-200-200.png'
|
||||
icon: '//img.alicdn.com/tfs/TB1FrT5r9BYBeNjy0FeXXbnmFXa-200-200.png',
|
||||
},
|
||||
{
|
||||
ext: /\.(zip|rar|arj|z|gz|iso|jar|ace|tar|uue|dmg|pkg|lzh|cab)$/i,
|
||||
icon: '//img.alicdn.com/tfs/TB10jmfr29TBuNjy0FcXXbeiFXa-200-200.png'
|
||||
icon: '//img.alicdn.com/tfs/TB10jmfr29TBuNjy0FcXXbeiFXa-200-200.png',
|
||||
},
|
||||
{
|
||||
ext: /\.[^.]+$/i,
|
||||
icon: '//img.alicdn.com/tfs/TB10.R4r3mTBuNjy1XbXXaMrVXa-200-200.png'
|
||||
}
|
||||
]
|
||||
icon: '//img.alicdn.com/tfs/TB10.R4r3mTBuNjy1XbXXaMrVXa-200-200.png',
|
||||
},
|
||||
];
|
||||
|
@ -28,7 +28,9 @@
|
||||
font-size: 13px;
|
||||
color: #636363;
|
||||
}
|
||||
.ant-upload-list-picture-card .ant-upload-list-item:hover .ant-upload-list-item-info::before {
|
||||
.ant-upload-list-picture-card
|
||||
.ant-upload-list-item:hover
|
||||
.ant-upload-list-item-info::before {
|
||||
display: none;
|
||||
}
|
||||
.ant-upload-list-picture-card .ant-upload-list-item-progress {
|
||||
@ -36,7 +38,7 @@
|
||||
pointer-events: none;
|
||||
}
|
||||
.ant-btn {
|
||||
background: rgba(0,0,0,.5);
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
// .anticon {
|
||||
// color: #1890ff;
|
||||
// }
|
||||
@ -55,7 +57,8 @@
|
||||
.ant-upload-list-picture-card .ant-upload-list-item-name {
|
||||
display: none;
|
||||
}
|
||||
.ant-upload-list-picture .ant-upload-list-item, .ant-upload-list-picture-card .ant-upload-list-item {
|
||||
.ant-upload-list-picture .ant-upload-list-item,
|
||||
.ant-upload-list-picture-card .ant-upload-list-item {
|
||||
padding: 1px;
|
||||
}
|
||||
}
|
@ -96,7 +96,7 @@ describe('user fields', () => {
|
||||
target: 'users',
|
||||
foreignKey: 'updated_by_id',
|
||||
},
|
||||
]
|
||||
],
|
||||
});
|
||||
|
||||
await db.sync();
|
||||
@ -106,14 +106,19 @@ describe('user fields', () => {
|
||||
|
||||
// 用户1 操作
|
||||
const user1 = await User.create();
|
||||
const postWithUser = await Post.create({}, { context: { state: { currentUser: user1 } } });
|
||||
const postWithUser = await Post.create(
|
||||
{},
|
||||
{ context: { state: { currentUser: user1 } } },
|
||||
);
|
||||
|
||||
const post = await Post.findOne(Post.parseApiJson({
|
||||
const post = await Post.findOne(
|
||||
Post.parseApiJson({
|
||||
filter: {
|
||||
id: postWithUser.id,
|
||||
},
|
||||
fields: ['createdBy1', 'updatedBy1', 'createdBy2', 'updatedBy2'],
|
||||
}));
|
||||
}),
|
||||
);
|
||||
|
||||
expect(post.createdBy1.id).toBe(user1.id);
|
||||
expect(post.updatedBy1.id).toBe(user1.id);
|
||||
@ -122,14 +127,19 @@ describe('user fields', () => {
|
||||
|
||||
// 换个用户
|
||||
const user2 = await User.create();
|
||||
await postWithUser.update({ title: 'title1' }, { context: { state: { currentUser: user2 } } });
|
||||
await postWithUser.update(
|
||||
{ title: 'title1' },
|
||||
{ context: { state: { currentUser: user2 } } },
|
||||
);
|
||||
|
||||
const post2 = await Post.findOne(Post.parseApiJson({
|
||||
const post2 = await Post.findOne(
|
||||
Post.parseApiJson({
|
||||
filter: {
|
||||
id: postWithUser.id,
|
||||
},
|
||||
fields: ['createdBy1', 'updatedBy1', 'createdBy2', 'updatedBy2'],
|
||||
}));
|
||||
}),
|
||||
);
|
||||
|
||||
expect(post2.createdBy1.id).toBe(user1.id);
|
||||
expect(post2.createdBy2.id).toBe(user1.id);
|
||||
@ -151,13 +161,19 @@ describe('user fields', () => {
|
||||
expect(postWithoutUser.created_by_id).toBe(null);
|
||||
expect(postWithoutUser.updated_by_id).toBe(null);
|
||||
// @ts-ignore
|
||||
const postWithUser = await Post.create({}, { context: { state: { currentUser } } });
|
||||
const postWithUser = await Post.create(
|
||||
{},
|
||||
{ context: { state: { currentUser } } },
|
||||
);
|
||||
expect(postWithUser.created_by_id).toBe(currentUser.id);
|
||||
expect(postWithUser.updated_by_id).toBe(currentUser.id);
|
||||
|
||||
// 更新数据 createdBy 数据不变
|
||||
// @ts-ignore
|
||||
await postWithUser.update({ title: 'title1' }, { context: { state: { currentUser: user2 } } });
|
||||
await postWithUser.update(
|
||||
{ title: 'title1' },
|
||||
{ context: { state: { currentUser: user2 } } },
|
||||
);
|
||||
expect(postWithUser.created_by_id).toBe(currentUser.id);
|
||||
expect(postWithUser.updated_by_id).toBe(user2.id);
|
||||
});
|
||||
@ -170,11 +186,14 @@ describe('user fields', () => {
|
||||
const user2 = await User.create();
|
||||
const Post = db.getModel('posts');
|
||||
|
||||
const post = await Post.create({
|
||||
const post = await Post.create(
|
||||
{
|
||||
created_by_id: user1.id,
|
||||
updated_by_id: user1.id,
|
||||
// @ts-ignore
|
||||
}, { context: { state: { currentUser: user2 } } });
|
||||
},
|
||||
{ context: { state: { currentUser: user2 } } },
|
||||
);
|
||||
expect(post.created_by_id).toBe(user1.id);
|
||||
expect(post.updated_by_id).toBe(user1.id);
|
||||
});
|
||||
@ -189,9 +208,9 @@ describe('user fields', () => {
|
||||
fields: [
|
||||
{
|
||||
type: 'string',
|
||||
name: 'title'
|
||||
}
|
||||
]
|
||||
name: 'title',
|
||||
},
|
||||
],
|
||||
});
|
||||
await db.sync();
|
||||
const User = db.getModel('users');
|
||||
@ -201,7 +220,10 @@ describe('user fields', () => {
|
||||
const post = await Post.create();
|
||||
expect(post.updated_by_id).toBe(null);
|
||||
// @ts-ignore
|
||||
await post.update({ title: 'title' }, { context: { state: { currentUser } } })
|
||||
await post.update(
|
||||
{ title: 'title' },
|
||||
{ context: { state: { currentUser } } },
|
||||
);
|
||||
expect(post.updated_by_id).toBe(currentUser.id);
|
||||
});
|
||||
|
||||
@ -212,9 +234,9 @@ describe('user fields', () => {
|
||||
fields: [
|
||||
{
|
||||
type: 'string',
|
||||
name: 'title'
|
||||
}
|
||||
]
|
||||
name: 'title',
|
||||
},
|
||||
],
|
||||
});
|
||||
await db.sync();
|
||||
const User = db.getModel('users');
|
||||
@ -223,15 +245,21 @@ describe('user fields', () => {
|
||||
const Post = db.getModel('posts');
|
||||
let context = { state: { currentUser: user2 } };
|
||||
|
||||
const post = await Post.create({
|
||||
const post = await Post.create(
|
||||
{
|
||||
updated_by_id: user1.id,
|
||||
}, { context });
|
||||
},
|
||||
{ context },
|
||||
);
|
||||
expect(post.updated_by_id).toBe(user1.id);
|
||||
|
||||
await post.update({ title: 'title' }, { context });
|
||||
expect(post.updated_by_id).toBe(user2.id);
|
||||
|
||||
await post.update({ title: 'title', updated_by_id: user1.id }, { context });
|
||||
await post.update(
|
||||
{ title: 'title', updated_by_id: user1.id },
|
||||
{ context },
|
||||
);
|
||||
expect(post.updated_by_id).toBe(user1.id);
|
||||
|
||||
// 不同用户更新数据
|
||||
@ -252,9 +280,9 @@ describe('user fields', () => {
|
||||
fields: [
|
||||
{
|
||||
type: 'string',
|
||||
name: 'title'
|
||||
}
|
||||
]
|
||||
name: 'title',
|
||||
},
|
||||
],
|
||||
});
|
||||
await db.sync();
|
||||
const User = db.getModel('users');
|
||||
@ -263,18 +291,20 @@ describe('user fields', () => {
|
||||
const Post = db.getModel('posts');
|
||||
let context = { state: { currentUser: user2 } };
|
||||
|
||||
await Post.bulkCreate([
|
||||
{ title: 'title1' },
|
||||
{ title: 'title2' },
|
||||
]);
|
||||
await Post.bulkCreate([{ title: 'title1' }, { title: 'title2' }]);
|
||||
|
||||
await Post.update({ title: 'title3' }, {
|
||||
await Post.update(
|
||||
{ title: 'title3' },
|
||||
{
|
||||
where: { title: 'title1' },
|
||||
context
|
||||
});
|
||||
context,
|
||||
},
|
||||
);
|
||||
|
||||
const posts = await Post.findAll({ order: [['id', 'ASC']] });
|
||||
expect(posts.map(({ title, updated_by_id }) => ({ title, updated_by_id }))).toEqual([
|
||||
expect(
|
||||
posts.map(({ title, updated_by_id }) => ({ title, updated_by_id })),
|
||||
).toEqual([
|
||||
{ title: 'title3', updated_by_id: 2 },
|
||||
{ title: 'title2', updated_by_id: null },
|
||||
]);
|
||||
|
@ -62,7 +62,9 @@ export async function register(ctx: Context, next: Next) {
|
||||
}
|
||||
|
||||
export async function lostpassword(ctx: Context, next: Next) {
|
||||
const { values: { email } } = ctx.action.params;
|
||||
const {
|
||||
values: { email },
|
||||
} = ctx.action.params;
|
||||
if (!email) {
|
||||
ctx.throw(401, '请填写邮箱账号');
|
||||
}
|
||||
@ -82,7 +84,9 @@ export async function lostpassword(ctx: Context, next: Next) {
|
||||
}
|
||||
|
||||
export async function resetpassword(ctx: Context, next: Next) {
|
||||
const { values: { email, password, reset_token } } = ctx.action.params;
|
||||
const {
|
||||
values: { email, password, reset_token },
|
||||
} = ctx.action.params;
|
||||
const User = ctx.db.getModel('users');
|
||||
const user = await User.findOne({
|
||||
where: {
|
||||
|
@ -2,13 +2,12 @@ import { BelongsToOptions, BELONGSTO, FieldContext } from '@nocobase/database';
|
||||
import { setUserValue } from './utils';
|
||||
|
||||
export interface CreatedByOptions extends Omit<BelongsToOptions, 'type'> {
|
||||
type: 'createdBy' | 'createdby'
|
||||
type: 'createdBy' | 'createdby';
|
||||
}
|
||||
|
||||
export default class CreatedBy extends BELONGSTO {
|
||||
|
||||
static beforeBulkCreateHook(this: CreatedBy, models, { context }) {
|
||||
models.forEach(model => {
|
||||
models.forEach((model) => {
|
||||
setUserValue.call(this, model, { context });
|
||||
});
|
||||
}
|
||||
@ -22,7 +21,10 @@ export default class CreatedBy extends BELONGSTO {
|
||||
const { sourceTable, database } = context;
|
||||
const name = sourceTable.getName();
|
||||
database.on(`${name}.beforeCreate`, setUserValue.bind(this));
|
||||
database.on(`${name}.beforeBulkCreate`, CreatedBy.beforeBulkCreateHook.bind(this));
|
||||
database.on(
|
||||
`${name}.beforeBulkCreate`,
|
||||
CreatedBy.beforeBulkCreateHook.bind(this),
|
||||
);
|
||||
}
|
||||
|
||||
public getDataType(): Function {
|
||||
|
@ -2,18 +2,20 @@ import { BelongsToOptions, BELONGSTO, FieldContext } from '@nocobase/database';
|
||||
import { setUserValue } from './utils';
|
||||
|
||||
export interface UpdatedByOptions extends Omit<BelongsToOptions, 'type'> {
|
||||
type: 'updatedBy' | 'updatedby'
|
||||
type: 'updatedBy' | 'updatedby';
|
||||
}
|
||||
|
||||
export default class UpdatedBy extends BELONGSTO {
|
||||
|
||||
static beforeBulkCreateHook(this: UpdatedBy, models, { context }) {
|
||||
models.forEach(model => {
|
||||
models.forEach((model) => {
|
||||
setUserValue.call(this, model, { context });
|
||||
});
|
||||
}
|
||||
|
||||
static beforeBulkUpdateHook(this: UpdatedBy, { attributes, fields, context }) {
|
||||
static beforeBulkUpdateHook(
|
||||
this: UpdatedBy,
|
||||
{ attributes, fields, context },
|
||||
) {
|
||||
if (!context) {
|
||||
return;
|
||||
}
|
||||
@ -22,7 +24,9 @@ export default class UpdatedBy extends BELONGSTO {
|
||||
return;
|
||||
}
|
||||
fields.push(this.options.foreignKey);
|
||||
attributes[this.options.foreignKey] = currentUser.get(this.options.targetKey);
|
||||
attributes[this.options.foreignKey] = currentUser.get(
|
||||
this.options.targetKey,
|
||||
);
|
||||
}
|
||||
|
||||
constructor({ type, ...options }: UpdatedByOptions, context: FieldContext) {
|
||||
@ -36,9 +40,15 @@ export default class UpdatedBy extends BELONGSTO {
|
||||
const { sourceTable, database } = context;
|
||||
const name = sourceTable.getName();
|
||||
database.on(`${name}.beforeCreate`, setUserValue.bind(this));
|
||||
database.on(`${name}.beforeBulkCreate`, UpdatedBy.beforeBulkCreateHook.bind(this));
|
||||
database.on(
|
||||
`${name}.beforeBulkCreate`,
|
||||
UpdatedBy.beforeBulkCreateHook.bind(this),
|
||||
);
|
||||
database.on(`${name}.beforeUpdate`, setUserValue.bind(this));
|
||||
database.on(`${name}.beforeBulkUpdate`, UpdatedBy.beforeBulkUpdateHook.bind(this));
|
||||
database.on(
|
||||
`${name}.beforeBulkUpdate`,
|
||||
UpdatedBy.beforeBulkUpdateHook.bind(this),
|
||||
);
|
||||
}
|
||||
|
||||
public getDataType(): Function {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { CreatedBy, UpdatedBy } from ".";
|
||||
import { CreatedBy, UpdatedBy } from '.';
|
||||
|
||||
export function setUserValue(this: CreatedBy | UpdatedBy, model, { context }) {
|
||||
const { foreignKey } = this.options;
|
||||
@ -8,7 +8,7 @@ export function setUserValue(this: CreatedBy | UpdatedBy, model, { context }) {
|
||||
return;
|
||||
}
|
||||
const changed = model.changed();
|
||||
if (Array.isArray(changed) && changed.find(key => key === foreignKey)) {
|
||||
if (Array.isArray(changed) && changed.find((key) => key === foreignKey)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user