mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-08 06:59:26 +08:00
fix: import with date field (#5606)
* fix: import with dateOnly and datetimeNoTz field * fix: import with date field * fix: export datetime filed * fix: test * fix: test * fix: test * fix: unixtimestamp import * chore: test
This commit is contained in:
parent
3d512adade
commit
ef1ded8ff2
@ -10,11 +10,11 @@
|
|||||||
import { usePrefixCls } from '@formily/antd-v5/esm/__builtins__';
|
import { usePrefixCls } from '@formily/antd-v5/esm/__builtins__';
|
||||||
import { isArr } from '@formily/shared';
|
import { isArr } from '@formily/shared';
|
||||||
import {
|
import {
|
||||||
|
getDefaultFormat,
|
||||||
GetDefaultFormatProps,
|
GetDefaultFormatProps,
|
||||||
|
str2moment,
|
||||||
Str2momentOptions,
|
Str2momentOptions,
|
||||||
Str2momentValue,
|
Str2momentValue,
|
||||||
getDefaultFormat,
|
|
||||||
str2moment,
|
|
||||||
} from '@nocobase/utils/client';
|
} from '@nocobase/utils/client';
|
||||||
import cls from 'classnames';
|
import cls from 'classnames';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
@ -67,6 +67,7 @@ ReadPretty.DateRangePicker = function DateRangePicker(props: DateRangePickerRead
|
|||||||
const labels = m.map((m) => m.format(format));
|
const labels = m.map((m) => m.format(format));
|
||||||
return isArr(labels) ? labels.join('~') : labels;
|
return isArr(labels) ? labels.join('~') : labels;
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cls(prefixCls, props.className)} style={props.style}>
|
<div className={cls(prefixCls, props.className)} style={props.style}>
|
||||||
{getLabels()}
|
{getLabels()}
|
||||||
|
@ -39,7 +39,7 @@ describe('Date time interface', () => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'dateTime',
|
name: 'dateTime',
|
||||||
type: 'date',
|
type: 'datetime',
|
||||||
uiSchema: {
|
uiSchema: {
|
||||||
['x-component-props']: {
|
['x-component-props']: {
|
||||||
showTime: true,
|
showTime: true,
|
||||||
@ -74,20 +74,5 @@ describe('Date time interface', () => {
|
|||||||
expect(await interfaceInstance.toValue(42510)).toBe('2016-05-20T00:00:00.000Z');
|
expect(await interfaceInstance.toValue(42510)).toBe('2016-05-20T00:00:00.000Z');
|
||||||
expect(await interfaceInstance.toValue('42510')).toBe('2016-05-20T00:00:00.000Z');
|
expect(await interfaceInstance.toValue('42510')).toBe('2016-05-20T00:00:00.000Z');
|
||||||
expect(await interfaceInstance.toValue('2016-05-20T00:00:00.000Z')).toBe('2016-05-20T00:00:00.000Z');
|
expect(await interfaceInstance.toValue('2016-05-20T00:00:00.000Z')).toBe('2016-05-20T00:00:00.000Z');
|
||||||
expect(
|
|
||||||
await interfaceInstance.toValue('2016-05-20 04:22:22', {
|
|
||||||
field: testCollection.getField('dateOnly'),
|
|
||||||
}),
|
|
||||||
).toBe('2016-05-20T00:00:00.000Z');
|
|
||||||
expect(
|
|
||||||
await interfaceInstance.toValue('2016-05-20 01:00:00', {
|
|
||||||
field: testCollection.getField('dateTime'),
|
|
||||||
}),
|
|
||||||
).toBe(dayjs('2016-05-20 01:00:00').toISOString());
|
|
||||||
expect(
|
|
||||||
await interfaceInstance.toValue('2016-05-20 01:00:00', {
|
|
||||||
field: testCollection.getField('dateTimeGmt'),
|
|
||||||
}),
|
|
||||||
).toBe('2016-05-20T01:00:00.000Z');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
7
packages/core/database/src/interfaces/date-interface.ts
Normal file
7
packages/core/database/src/interfaces/date-interface.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import { DatetimeInterface } from './datetime-interface';
|
||||||
|
|
||||||
|
export class DateInterface extends DatetimeInterface {
|
||||||
|
toString(value: any, ctx?: any): any {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { BaseInterface } from './base-interface';
|
import { BaseInterface } from './base-interface';
|
||||||
import { getDefaultFormat, moment2str, str2moment } from '@nocobase/utils';
|
import { getDefaultFormat, str2moment } from '@nocobase/utils';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { getJsDateFromExcel } from 'excel-date-to-js';
|
import { getJsDateFromExcel } from 'excel-date-to-js';
|
||||||
|
|
||||||
@ -51,11 +51,7 @@ export class DatetimeInterface extends BaseInterface {
|
|||||||
} else if (isNumeric(value)) {
|
} else if (isNumeric(value)) {
|
||||||
return getJsDateFromExcel(value).toISOString();
|
return getJsDateFromExcel(value).toISOString();
|
||||||
} else if (typeof value === 'string') {
|
} else if (typeof value === 'string') {
|
||||||
const props = ctx.field?.options?.uiSchema?.['x-component-props'] || {};
|
return value;
|
||||||
const m = dayjs(value);
|
|
||||||
if (m.isValid()) {
|
|
||||||
return moment2str(m, props);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error(`Invalid date - ${value}`);
|
throw new Error(`Invalid date - ${value}`);
|
||||||
|
@ -0,0 +1,49 @@
|
|||||||
|
import { DatetimeInterface } from './datetime-interface';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import { getJsDateFromExcel } from 'excel-date-to-js';
|
||||||
|
import { getDefaultFormat, str2moment } from '@nocobase/utils';
|
||||||
|
|
||||||
|
function isDate(v) {
|
||||||
|
return v instanceof Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isNumeric(str: any) {
|
||||||
|
if (typeof str === 'number') return true;
|
||||||
|
if (typeof str != 'string') return false;
|
||||||
|
return !isNaN(str as any) && !isNaN(parseFloat(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
export class DatetimeNoTzInterface extends DatetimeInterface {
|
||||||
|
async toValue(value: any, ctx: any = {}): Promise<any> {
|
||||||
|
if (!value) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof value === 'string') {
|
||||||
|
const match = /^(\d{4})[-/]?(\d{2})[-/]?(\d{2})$/.exec(value);
|
||||||
|
if (match) {
|
||||||
|
return `${match[1]}-${match[2]}-${match[3]}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dayjs.isDayjs(value)) {
|
||||||
|
return value;
|
||||||
|
} else if (isDate(value)) {
|
||||||
|
return value;
|
||||||
|
} else if (isNumeric(value)) {
|
||||||
|
const date = getJsDateFromExcel(value);
|
||||||
|
return `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`;
|
||||||
|
} else if (typeof value === 'string') {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(`Invalid date - ${value}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
toString(value: any, ctx?: any) {
|
||||||
|
const props = this.options?.uiSchema?.['x-component-props'] ?? {};
|
||||||
|
const format = getDefaultFormat(props);
|
||||||
|
const m = str2moment(value, { ...props });
|
||||||
|
return m ? m.format(format) : '';
|
||||||
|
}
|
||||||
|
}
|
@ -12,4 +12,6 @@ export * from './percent-interface';
|
|||||||
export * from './multiple-select-interface';
|
export * from './multiple-select-interface';
|
||||||
export * from './select-interface';
|
export * from './select-interface';
|
||||||
export * from './datetime-interface';
|
export * from './datetime-interface';
|
||||||
|
export * from './datetime-no-tz-interface';
|
||||||
export * from './boolean-interface';
|
export * from './boolean-interface';
|
||||||
|
export * from './date-interface';
|
||||||
|
@ -10,7 +10,9 @@
|
|||||||
import Database from '../database';
|
import Database from '../database';
|
||||||
import {
|
import {
|
||||||
BooleanInterface,
|
BooleanInterface,
|
||||||
|
DateInterface,
|
||||||
DatetimeInterface,
|
DatetimeInterface,
|
||||||
|
DatetimeNoTzInterface,
|
||||||
MultipleSelectInterface,
|
MultipleSelectInterface,
|
||||||
PercentInterface,
|
PercentInterface,
|
||||||
SelectInterface,
|
SelectInterface,
|
||||||
@ -36,6 +38,9 @@ const interfaces = {
|
|||||||
radioGroup: SelectInterface,
|
radioGroup: SelectInterface,
|
||||||
percent: PercentInterface,
|
percent: PercentInterface,
|
||||||
datetime: DatetimeInterface,
|
datetime: DatetimeInterface,
|
||||||
|
datetimeNoTz: DatetimeNoTzInterface,
|
||||||
|
unixTimestamp: DatetimeInterface,
|
||||||
|
date: DateInterface,
|
||||||
createdAt: DatetimeInterface,
|
createdAt: DatetimeInterface,
|
||||||
updatedAt: DatetimeInterface,
|
updatedAt: DatetimeInterface,
|
||||||
boolean: BooleanInterface,
|
boolean: BooleanInterface,
|
||||||
|
@ -78,7 +78,7 @@ const toMoment = (val: any, options?: Str2momentOptions) => {
|
|||||||
if (!val) {
|
if (!val) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const offset = options.utcOffset || -1 * new Date().getTimezoneOffset();
|
const offset = options.utcOffset !== undefined ? options.utcOffset : -1 * new Date().getTimezoneOffset();
|
||||||
const { gmt, picker, utc = true } = options;
|
const { gmt, picker, utc = true } = options;
|
||||||
if (dayjs(val).isValid()) {
|
if (dayjs(val).isValid()) {
|
||||||
if (!utc) {
|
if (!utc) {
|
||||||
|
@ -31,6 +31,122 @@ describe('export to xlsx with preset', () => {
|
|||||||
await app.destroy();
|
await app.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('export with date field', () => {
|
||||||
|
let Post;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
Post = app.db.collection({
|
||||||
|
name: 'posts',
|
||||||
|
fields: [
|
||||||
|
{ type: 'string', name: 'title' },
|
||||||
|
{
|
||||||
|
name: 'datetime',
|
||||||
|
type: 'datetime',
|
||||||
|
interface: 'datetime',
|
||||||
|
uiSchema: {
|
||||||
|
'x-component-props': { picker: 'date', dateFormat: 'YYYY-MM-DD', gmt: false, showTime: false, utc: true },
|
||||||
|
type: 'string',
|
||||||
|
'x-component': 'DatePicker',
|
||||||
|
title: 'dateTz',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'dateOnly',
|
||||||
|
type: 'dateOnly',
|
||||||
|
interface: 'date',
|
||||||
|
defaultToCurrentTime: false,
|
||||||
|
onUpdateToCurrentTime: false,
|
||||||
|
timezone: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'datetimeNoTz',
|
||||||
|
type: 'datetimeNoTz',
|
||||||
|
interface: 'datetimeNoTz',
|
||||||
|
uiSchema: {
|
||||||
|
'x-component-props': { picker: 'date', dateFormat: 'YYYY-MM-DD', gmt: false, showTime: false, utc: true },
|
||||||
|
type: 'string',
|
||||||
|
'x-component': 'DatePicker',
|
||||||
|
title: 'dateTz',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'unixTimestamp',
|
||||||
|
type: 'unixTimestamp',
|
||||||
|
interface: 'unixTimestamp',
|
||||||
|
uiSchema: {
|
||||||
|
'x-component-props': {
|
||||||
|
picker: 'date',
|
||||||
|
dateFormat: 'YYYY-MM-DD',
|
||||||
|
showTime: true,
|
||||||
|
timeFormat: 'HH:mm:ss',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
await app.db.sync();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should export with datetime field', async () => {
|
||||||
|
await Post.repository.create({
|
||||||
|
values: {
|
||||||
|
title: 'p1',
|
||||||
|
datetime: '2024-05-10T01:42:35.000Z',
|
||||||
|
dateOnly: '2024-05-10',
|
||||||
|
datetimeNoTz: '2024-01-01 00:00:00',
|
||||||
|
unixTimestamp: '2024-05-10T01:42:35.000Z',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const exporter = new XlsxExporter({
|
||||||
|
collectionManager: app.mainDataSource.collectionManager,
|
||||||
|
collection: Post,
|
||||||
|
chunkSize: 10,
|
||||||
|
columns: [
|
||||||
|
{ dataIndex: ['title'], defaultTitle: 'Title' },
|
||||||
|
{
|
||||||
|
dataIndex: ['datetime'],
|
||||||
|
defaultTitle: 'datetime',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: ['dateOnly'],
|
||||||
|
defaultTitle: 'dateOnly',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: ['datetimeNoTz'],
|
||||||
|
defaultTitle: 'datetimeNoTz',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: ['unixTimestamp'],
|
||||||
|
defaultTitle: 'unixTimestamp',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const wb = await exporter.run();
|
||||||
|
|
||||||
|
const xlsxFilePath = path.resolve(__dirname, `t_${uid()}.xlsx`);
|
||||||
|
|
||||||
|
try {
|
||||||
|
XLSX.writeFile(wb, xlsxFilePath);
|
||||||
|
|
||||||
|
// read xlsx file
|
||||||
|
const workbook = XLSX.readFile(xlsxFilePath);
|
||||||
|
const firstSheet = workbook.Sheets[workbook.SheetNames[0]];
|
||||||
|
const sheetData = XLSX.utils.sheet_to_json(firstSheet, { header: 1 });
|
||||||
|
|
||||||
|
const firstUser = sheetData[1];
|
||||||
|
expect(firstUser[1]).toEqual('2024-05-10');
|
||||||
|
expect(firstUser[2]).toEqual('2024-05-10');
|
||||||
|
expect(firstUser[3]).toEqual('2024-01-01');
|
||||||
|
expect(firstUser[4]).toEqual('2024-05-10 01:42:35');
|
||||||
|
} finally {
|
||||||
|
fs.unlinkSync(xlsxFilePath);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should export with checkbox field', async () => {
|
it('should export with checkbox field', async () => {
|
||||||
const Post = app.db.collection({
|
const Post = app.db.collection({
|
||||||
name: 'posts',
|
name: 'posts',
|
||||||
@ -520,7 +636,7 @@ describe('export to xlsx', () => {
|
|||||||
title: 'test_date',
|
title: 'test_date',
|
||||||
},
|
},
|
||||||
name: 'test_date',
|
name: 'test_date',
|
||||||
type: 'date',
|
type: 'datetime',
|
||||||
interface: 'datetime',
|
interface: 'datetime',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -548,11 +664,7 @@ describe('export to xlsx', () => {
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
const wb = await exporter.run({
|
const wb = await exporter.run();
|
||||||
get() {
|
|
||||||
return '+08:00';
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const xlsxFilePath = path.resolve(__dirname, `t_${uid()}.xlsx`);
|
const xlsxFilePath = path.resolve(__dirname, `t_${uid()}.xlsx`);
|
||||||
try {
|
try {
|
||||||
@ -564,7 +676,7 @@ describe('export to xlsx', () => {
|
|||||||
const sheetData = XLSX.utils.sheet_to_json(firstSheet, { header: 1 });
|
const sheetData = XLSX.utils.sheet_to_json(firstSheet, { header: 1 });
|
||||||
|
|
||||||
const firstUser = sheetData[1];
|
const firstUser = sheetData[1];
|
||||||
expect(firstUser).toEqual(['some_title', '2024-05-10 09:42:35']);
|
expect(firstUser).toEqual(['some_title', '2024-05-10 01:42:35']);
|
||||||
} finally {
|
} finally {
|
||||||
fs.unlinkSync(xlsxFilePath);
|
fs.unlinkSync(xlsxFilePath);
|
||||||
}
|
}
|
||||||
|
@ -38,24 +38,143 @@ describe('xlsx importer', () => {
|
|||||||
name: 'name',
|
name: 'name',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'date',
|
type: 'datetime',
|
||||||
name: 'date',
|
name: 'datetime',
|
||||||
interface: 'datetime',
|
interface: 'datetime',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: 'datetimeNoTz',
|
||||||
|
name: 'datetimeNoTz',
|
||||||
|
interface: 'datetimeNoTz',
|
||||||
|
uiSchema: {
|
||||||
|
'x-component-props': {
|
||||||
|
picker: 'date',
|
||||||
|
dateFormat: 'YYYY-MM-DD',
|
||||||
|
showTime: true,
|
||||||
|
timeFormat: 'HH:mm:ss',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'dateOnly',
|
||||||
|
name: 'dateOnly',
|
||||||
|
interface: 'date',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'unixTimestamp',
|
||||||
|
name: 'unixTimestamp',
|
||||||
|
interface: 'unixTimestamp',
|
||||||
|
uiSchema: {
|
||||||
|
'x-component-props': {
|
||||||
|
picker: 'date',
|
||||||
|
dateFormat: 'YYYY-MM-DD',
|
||||||
|
showTime: true,
|
||||||
|
timeFormat: 'HH:mm:ss',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
await app.db.sync();
|
await app.db.sync();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should import with date', async () => {
|
it('should import with dateOnly', async () => {
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
dataIndex: ['name'],
|
dataIndex: ['name'],
|
||||||
defaultTitle: '姓名',
|
defaultTitle: '姓名',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
dataIndex: ['date'],
|
dataIndex: ['dateOnly'],
|
||||||
|
defaultTitle: '日期',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const templateCreator = new TemplateCreator({
|
||||||
|
collection: User,
|
||||||
|
columns,
|
||||||
|
});
|
||||||
|
|
||||||
|
const template = await templateCreator.run();
|
||||||
|
|
||||||
|
const worksheet = template.Sheets[template.SheetNames[0]];
|
||||||
|
|
||||||
|
XLSX.utils.sheet_add_aoa(
|
||||||
|
worksheet,
|
||||||
|
[
|
||||||
|
['test', 77383],
|
||||||
|
['test2', '2021-10-18'],
|
||||||
|
],
|
||||||
|
{ origin: 'A2' },
|
||||||
|
);
|
||||||
|
|
||||||
|
const importer = new XlsxImporter({
|
||||||
|
collectionManager: app.mainDataSource.collectionManager,
|
||||||
|
collection: User,
|
||||||
|
columns,
|
||||||
|
workbook: template,
|
||||||
|
});
|
||||||
|
|
||||||
|
await importer.run();
|
||||||
|
|
||||||
|
const users = (await User.repository.find()).map((user) => user.toJSON());
|
||||||
|
expect(users[0]['dateOnly']).toBe('2111-11-12');
|
||||||
|
expect(users[1]['dateOnly']).toBe('2021-10-18');
|
||||||
|
});
|
||||||
|
|
||||||
|
it.skipIf(process.env['DB_DIALECT'] === 'sqlite')('should import with datetimeNoTz', async () => {
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
dataIndex: ['name'],
|
||||||
|
defaultTitle: '姓名',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: ['datetimeNoTz'],
|
||||||
|
defaultTitle: '日期',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const templateCreator = new TemplateCreator({
|
||||||
|
collection: User,
|
||||||
|
columns,
|
||||||
|
});
|
||||||
|
|
||||||
|
const template = await templateCreator.run();
|
||||||
|
|
||||||
|
const worksheet = template.Sheets[template.SheetNames[0]];
|
||||||
|
|
||||||
|
XLSX.utils.sheet_add_aoa(
|
||||||
|
worksheet,
|
||||||
|
[
|
||||||
|
['test', 77383],
|
||||||
|
['test2', '2021-10-18'],
|
||||||
|
],
|
||||||
|
{ origin: 'A2' },
|
||||||
|
);
|
||||||
|
|
||||||
|
const importer = new XlsxImporter({
|
||||||
|
collectionManager: app.mainDataSource.collectionManager,
|
||||||
|
collection: User,
|
||||||
|
columns,
|
||||||
|
workbook: template,
|
||||||
|
});
|
||||||
|
|
||||||
|
await importer.run();
|
||||||
|
|
||||||
|
const users = (await User.repository.find()).map((user) => user.toJSON());
|
||||||
|
expect(users[0]['datetimeNoTz']).toBe('2111-11-12 00:00:00');
|
||||||
|
expect(users[1]['datetimeNoTz']).toBe('2021-10-18 00:00:00');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should import with unixTimestamp', async () => {
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
dataIndex: ['name'],
|
||||||
|
defaultTitle: '姓名',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: ['unixTimestamp'],
|
||||||
defaultTitle: '日期',
|
defaultTitle: '日期',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@ -80,11 +199,44 @@ describe('xlsx importer', () => {
|
|||||||
|
|
||||||
await importer.run();
|
await importer.run();
|
||||||
|
|
||||||
expect(await User.repository.count()).toBe(1);
|
const users = (await User.repository.find()).map((user) => user.toJSON());
|
||||||
|
expect(moment(users[0]['unixTimestamp']).toISOString()).toEqual('2111-11-12T00:00:00.000Z');
|
||||||
|
});
|
||||||
|
|
||||||
const user = await User.repository.findOne();
|
it('should import with datetimeTz', async () => {
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
dataIndex: ['name'],
|
||||||
|
defaultTitle: '姓名',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataIndex: ['datetime'],
|
||||||
|
defaultTitle: '日期',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
expect(moment(user.get('date')).format('YYYY-MM-DD')).toBe('2111-11-12');
|
const templateCreator = new TemplateCreator({
|
||||||
|
collection: User,
|
||||||
|
columns,
|
||||||
|
});
|
||||||
|
|
||||||
|
const template = await templateCreator.run();
|
||||||
|
|
||||||
|
const worksheet = template.Sheets[template.SheetNames[0]];
|
||||||
|
|
||||||
|
XLSX.utils.sheet_add_aoa(worksheet, [['test', 77383]], { origin: 'A2' });
|
||||||
|
|
||||||
|
const importer = new XlsxImporter({
|
||||||
|
collectionManager: app.mainDataSource.collectionManager,
|
||||||
|
collection: User,
|
||||||
|
columns,
|
||||||
|
workbook: template,
|
||||||
|
});
|
||||||
|
|
||||||
|
await importer.run();
|
||||||
|
|
||||||
|
const users = (await User.repository.find()).map((user) => user.toJSON());
|
||||||
|
expect(moment(users[0]['datetime']).toISOString()).toEqual('2111-11-12T00:00:00.000Z');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user