From 25889515fb9eec80da1dfa93d3761721dfe939be Mon Sep 17 00:00:00 2001 From: aaaaaajie Date: Tue, 15 Apr 2025 20:26:31 +0800 Subject: [PATCH] fix: fixed an error importing xlsx time field --- .../core/database/src/interfaces/index.ts | 1 + .../database/src/interfaces/time-interface.ts | 26 ++++++++++ .../core/database/src/interfaces/utils.ts | 2 + .../server/__tests__/xlsx-importer.test.ts | 49 +++++++++++++++++++ .../src/server/actions/import-xlsx.ts | 1 + 5 files changed, 79 insertions(+) create mode 100644 packages/core/database/src/interfaces/time-interface.ts diff --git a/packages/core/database/src/interfaces/index.ts b/packages/core/database/src/interfaces/index.ts index 038ada52cc..aebd38d8d1 100644 --- a/packages/core/database/src/interfaces/index.ts +++ b/packages/core/database/src/interfaces/index.ts @@ -15,3 +15,4 @@ export * from './datetime-interface'; export * from './datetime-no-tz-interface'; export * from './boolean-interface'; export * from './date-interface'; +export * from './time-interface'; diff --git a/packages/core/database/src/interfaces/time-interface.ts b/packages/core/database/src/interfaces/time-interface.ts new file mode 100644 index 0000000000..95385b4eee --- /dev/null +++ b/packages/core/database/src/interfaces/time-interface.ts @@ -0,0 +1,26 @@ +/** + * This file is part of the NocoBase (R) project. + * Copyright (c) 2020-2024 NocoBase Co., Ltd. + * Authors: NocoBase Team. + * + * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License. + * For more information, please refer to: https://www.nocobase.com/agreement. + */ + +import dayjs from 'dayjs'; +import { BaseInterface } from './base-interface'; + +export class TimeInterface extends BaseInterface { + toValue(value: any, ctx?: any) { + if (this.validate(value)) { + const result = dayjs.utc(value).format('HH:mm:ss'); + return result; + } + return value; + } + + validate(value) { + const result = dayjs(value).isValid(); + return result; + } +} diff --git a/packages/core/database/src/interfaces/utils.ts b/packages/core/database/src/interfaces/utils.ts index 170687f6e5..cc10790ad0 100644 --- a/packages/core/database/src/interfaces/utils.ts +++ b/packages/core/database/src/interfaces/utils.ts @@ -16,6 +16,7 @@ import { MultipleSelectInterface, PercentInterface, SelectInterface, + TimeInterface, } from './index'; import { ManyToOneInterface } from './many-to-one-interface'; import { ManyToManyInterface } from './many-to-many-interface'; @@ -50,6 +51,7 @@ const interfaces = { o2m: OneToManyInterface, m2o: ManyToOneInterface, m2m: ManyToManyInterface, + time: TimeInterface, }; export function registerInterfaces(db: Database) { diff --git a/packages/plugins/@nocobase/plugin-action-import/src/server/__tests__/xlsx-importer.test.ts b/packages/plugins/@nocobase/plugin-action-import/src/server/__tests__/xlsx-importer.test.ts index 85cb90ca9a..21153d3760 100644 --- a/packages/plugins/@nocobase/plugin-action-import/src/server/__tests__/xlsx-importer.test.ts +++ b/packages/plugins/@nocobase/plugin-action-import/src/server/__tests__/xlsx-importer.test.ts @@ -2155,4 +2155,53 @@ describe('xlsx importer', () => { expect(await Post.repository.count()).toBe(1); }); + + it('should import time field successfully', async () => { + const TimeCollection = app.db.collection({ + name: 'time_tests', + fields: [ + { + type: 'time', + name: 'brithtime', + }, + ], + }); + + await app.db.sync(); + const templateCreator = new TemplateCreator({ + collection: TimeCollection, + explain: 'test', + columns: [ + { + dataIndex: ['birthtime'], + defaultTitle: '出生时间', + }, + ], + }); + + const template = (await templateCreator.run({ returnXLSXWorkbook: true })) as XLSX.WorkBook; + + const worksheet = template.Sheets[template.SheetNames[0]]; + + XLSX.utils.sheet_add_aoa(worksheet, [['12:12:12']], { + origin: 'A3', + }); + + const importer = new XlsxImporter({ + collectionManager: app.mainDataSource.collectionManager, + collection: TimeCollection, + explain: 'test', + columns: [ + { + dataIndex: ['brithtime'], + defaultTitle: '出生时间', + }, + ], + workbook: template, + }); + + await importer.run(); + const count = await TimeCollection.repository.count(); + expect(count).toBe(1); + }); }); diff --git a/packages/plugins/@nocobase/plugin-action-import/src/server/actions/import-xlsx.ts b/packages/plugins/@nocobase/plugin-action-import/src/server/actions/import-xlsx.ts index 8f8b75516f..9d63a78935 100644 --- a/packages/plugins/@nocobase/plugin-action-import/src/server/actions/import-xlsx.ts +++ b/packages/plugins/@nocobase/plugin-action-import/src/server/actions/import-xlsx.ts @@ -36,6 +36,7 @@ async function importXlsxAction(ctx: Context, next: Next) { const workbook = XLSX.read(ctx.file.buffer, { type: 'buffer', sheetRows: readLimit, + cellDates: true, }); const repository = ctx.getCurrentRepository() as Repository;