diff --git a/packages/core/client/src/schema-component/antd/rich-text/RichText.tsx b/packages/core/client/src/schema-component/antd/rich-text/RichText.tsx index fb0aa7bbec9..49de46dc2ee 100644 --- a/packages/core/client/src/schema-component/antd/rich-text/RichText.tsx +++ b/packages/core/client/src/schema-component/antd/rich-text/RichText.tsx @@ -9,9 +9,11 @@ import { connect, mapProps, mapReadPretty } from '@formily/react'; import React from 'react'; +import { css } from '@emotion/css'; +import classNames from 'classnames'; import { lazy } from '../../../lazy-helper'; import { isVariable } from '../../../variables/utils/isVariable'; -import { Input, ReadPretty as InputReadPretty } from '../input'; +import { ReadPretty as InputReadPretty } from '../input'; import { useStyles } from './style'; const ReactQuill = lazy(() => import('react-quill')); @@ -37,9 +39,23 @@ export const RichText = connect( ]; const { value, defaultValue, onChange, disabled, modules: propsModules, formats: propsFormats } = props; const resultValue = isVariable(value || defaultValue) ? undefined : value || ''; + const quillDisabled = css` + .ql-container.ql-disabled { + background-color: #f5f5f5; /* 灰色背景 */ + color: #999; + opacity: 0.7; + cursor: not-allowed; + pointer-events: none; + border: 1px solid #d9d9d9; /* 模拟 input 的禁用边框 */ + border-radius: 6px; + } + `; + return wrapSSR( { reading.push(promise); // eslint-disable-next-line promise/catch-or-return @@ -117,7 +119,7 @@ export class MemoryEventQueueAdapter implements IEventQueueAdapter { this.reading.set(channel, reading); }; - constructor(private options: { appName: string }) { + constructor(private options: { appName: string; logger: SystemLogger }) { this.emitter.setMaxListeners(0); } @@ -132,20 +134,21 @@ export class MemoryEventQueueAdapter implements IEventQueueAdapter { async loadFromStorage() { let queues = {}; let exists = false; + const { logger } = this.options; try { await fs.stat(this.storagePath); exists = true; } catch (ex) { - console.info(`memory queue storage file not found, skip`); + logger.info(`memory queue storage file not found, skip`); } if (exists) { try { const queueJson = await fs.readFile(this.storagePath); queues = JSON.parse(queueJson.toString()); - console.debug('memory queue loaded from storage', queues); + logger.debug('memory queue loaded from storage', queues); await fs.unlink(this.storagePath); } catch (ex) { - console.error('failed to load queue from storage', ex); + logger.error('failed to load queue from storage', ex); } } this.queues = new Map(Object.entries(queues)); @@ -159,12 +162,13 @@ export class MemoryEventQueueAdapter implements IEventQueueAdapter { return acc; }, {}); + const { logger } = this.options; if (Object.keys(queues).length) { await fs.mkdir(path.dirname(this.storagePath), { recursive: true }); await fs.writeFile(this.storagePath, JSON.stringify(queues)); - console.debug('memory queue saved to storage', queues); + logger.debug('memory queue saved to storage', queues); } else { - console.debug('memory queue empty, no need to save to storage'); + logger.debug('memory queue empty, no need to save to storage'); } } @@ -195,14 +199,15 @@ export class MemoryEventQueueAdapter implements IEventQueueAdapter { if (!this.connected) { return; } + const { logger } = this.options; this.connected = false; if (this.processing) { - console.info('memory queue waiting for processing job...'); + logger.info('memory queue waiting for processing job...'); await this.processing; - console.info('memory queue job cleaned'); + logger.info('memory queue job cleaned'); } - console.log('memory queue gracefully shutting down...'); + logger.info('memory queue gracefully shutting down...'); await this.saveToStorage(); } @@ -242,7 +247,8 @@ export class MemoryEventQueueAdapter implements IEventQueueAdapter { const queue = this.queues.get(channel); const message = { id: randomUUID(), content, options }; queue.push(message); - console.debug(`memory queue (${channel}) published message`, content); + const { logger } = this.options; + logger.debug(`memory queue (${channel}) published message`, content); setImmediate(() => { this.emitter.emit(channel, channel); @@ -272,8 +278,9 @@ export class MemoryEventQueueAdapter implements IEventQueueAdapter { if (!queue?.length) { return []; } + const { logger } = this.options; const messages = queue.slice(0, n); - console.debug(`memory queue (${channel}) read ${messages.length} messages`, messages); + logger.debug(`memory queue (${channel}) read ${messages.length} messages`, messages); queue.splice(0, messages.length); const batch = messages.map(({ id, ...message }) => this.process(channel, { id, message })); return batch; @@ -282,7 +289,8 @@ export class MemoryEventQueueAdapter implements IEventQueueAdapter { async process(channel: string, { id, message }) { const event = this.events.get(channel); const { content, options: { timeout = QUEUE_DEFAULT_ACK_TIMEOUT, maxRetries = 0, retried = 0 } = {} } = message; - console.debug(`memory queue (${channel}) processing message (${id})...`, content); + const { logger } = this.options; + logger.debug(`memory queue (${channel}) processing message (${id})...`, content); return (async () => event.process(content, { id, @@ -290,12 +298,12 @@ export class MemoryEventQueueAdapter implements IEventQueueAdapter { signal: AbortSignal.timeout(timeout), }))() .then(() => { - console.debug(`memory queue (${channel}) consumed message (${id})`); + logger.debug(`memory queue (${channel}) consumed message (${id})`); }) .catch((ex) => { if (maxRetries > 0 && retried < maxRetries) { const currentRetry = retried + 1; - console.warn( + logger.warn( `memory queue (${channel}) consum message (${id}) failed, retrying (${currentRetry} / ${maxRetries})...`, ex, ); @@ -303,7 +311,7 @@ export class MemoryEventQueueAdapter implements IEventQueueAdapter { this.publish(channel, content, { timeout, maxRetries, retried: currentRetry, timestamp: Date.now() }); }, 500); } else { - console.error(ex); + logger.error(ex); } }); } @@ -322,7 +330,7 @@ export class EventQueue { protected options: EventQueueOptions = {}, ) { if (app.serving()) { - this.setAdapter(new MemoryEventQueueAdapter({ appName: this.app.name })); + this.setAdapter(new MemoryEventQueueAdapter({ appName: this.app.name, logger: this.app.logger })); app.on('afterStart', async () => { await this.connect(); diff --git a/packages/plugins/@nocobase/plugin-public-forms/src/client/components/components/MobileDatePicker.tsx b/packages/plugins/@nocobase/plugin-public-forms/src/client/components/components/MobileDatePicker.tsx index 68ec6ce4022..da30a1af84a 100644 --- a/packages/plugins/@nocobase/plugin-public-forms/src/client/components/components/MobileDatePicker.tsx +++ b/packages/plugins/@nocobase/plugin-public-forms/src/client/components/components/MobileDatePicker.tsx @@ -38,6 +38,7 @@ const MobileDateTimePicker = connect( timeFormat = 'HH:mm', showTime = false, picker, + disabled, ...rest } = props; const [visible, setVisible] = useState(false); @@ -73,11 +74,12 @@ const MobileDateTimePicker = connect( }, []); return ( <> -
setVisible(true)}> +
!disabled && setVisible(true)}> setVisible(true)} value={value} picker={picker} + disabled={disabled} {...rest} popupStyle={{ display: 'none' }} style={{ pointerEvents: 'none', width: '100%' }} diff --git a/packages/plugins/@nocobase/plugin-public-forms/src/client/components/components/MobilePicker.tsx b/packages/plugins/@nocobase/plugin-public-forms/src/client/components/components/MobilePicker.tsx index b0180e40d8c..952a5da875d 100644 --- a/packages/plugins/@nocobase/plugin-public-forms/src/client/components/components/MobilePicker.tsx +++ b/packages/plugins/@nocobase/plugin-public-forms/src/client/components/components/MobilePicker.tsx @@ -15,7 +15,7 @@ import { useTranslation } from 'react-i18next'; const MobilePicker = connect( (props) => { - const { value, onChange, options = [], mode } = props; + const { value, onChange, options = [], mode, disabled } = props; const { t } = useTranslation(); const [visible, setVisible] = useState(false); const [selected, setSelected] = useState(value || []); @@ -38,12 +38,13 @@ const MobilePicker = connect( return ( <> -
setVisible(true)}> +
!disabled && setVisible(true)}>