提交 506c37f5 authored 作者: 王鹏飞's avatar 王鹏飞

chore: update pnpm-workspace.yaml to exclude minimum release age for vite@8.2.2

上级 91d8ca2c
...@@ -55,10 +55,10 @@ ...@@ -55,10 +55,10 @@
"@vitejs/plugin-react": "^6.0.5", "@vitejs/plugin-react": "^6.0.5",
"jsdom": "^29.1.1", "jsdom": "^29.1.1",
"less": "^4.2.0", "less": "^4.2.0",
"oxfmt": "^0.59.0", "oxfmt": "^0.64.0",
"oxlint": "^1.74.0", "oxlint": "^1.79.0",
"typescript": "^7.0.2", "typescript": "^7.0.2",
"vite": "^8.2.1", "vite": "^8.2.2",
"vite-plugin-mkcert": "^2.1.0", "vite-plugin-mkcert": "^2.1.0",
"vitest": "^4.1.10" "vitest": "^4.1.10"
} }
......
...@@ -70,14 +70,6 @@ dd { ...@@ -70,14 +70,6 @@ dd {
display: inline-block !important; display: inline-block !important;
} }
.ant-space-item {
.ant-btn.css-dev-only-do-not-override-1scgnrh {
display: flex;
align-items: center;
justify-content: center;
}
}
.form-devices-inline { .form-devices-inline {
.ant-form-inline { .ant-form-inline {
.ant-form-item { .ant-form-item {
......
...@@ -2,13 +2,13 @@ ...@@ -2,13 +2,13 @@
.wrap-phone-privew { .wrap-phone-privew {
.ant-modal { .ant-modal {
.ant-modal-close { .phone-close {
inset-inline-end: 17px; inset-inline-end: 17px;
top: 0px; top: 0;
right: 0; right: 0;
} }
.ant-modal-content { .phone-content {
background: url('@/assets/images/phone_6.7.png') no-repeat; background: url('@/assets/images/phone_6.7.png') no-repeat;
background-size: 100% 100%; background-size: 100% 100%;
box-shadow: none; box-shadow: none;
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
border-radius: 48px; border-radius: 48px;
padding: 36px 32px 34px 32px; padding: 36px 32px 34px 32px;
} }
.priview-modal { .preview-modal {
padding-top: 40px; padding-top: 40px;
width: 430px; width: 430px;
height: 932px; height: 932px;
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
width: 430px; width: 430px;
border-radius: 30px; border-radius: 30px;
} }
.previee-container { .preview-container {
height: 100%; height: 100%;
overflow: hidden; overflow: hidden;
position: relative; position: relative;
...@@ -431,7 +431,7 @@ ...@@ -431,7 +431,7 @@
} }
// 画廊展示 // 画廊展示
.gallery-prview-container { .gallery-preview-container {
.gallery-img { .gallery-img {
max-height: 300px; max-height: 300px;
height: 300px; height: 300px;
...@@ -680,17 +680,17 @@ ...@@ -680,17 +680,17 @@
} }
} }
.priview-drawer-container { .preview-drawer-container {
height: 932px; height: 932px;
top: 42px; top: 42px;
left: 0px; left: 0px;
width: 430px; width: 430px;
border-radius: 15px 0 40px 40px; border-radius: 15px 0 40px 40px;
overflow: hidden; overflow: hidden;
.priview-drawer-header { .preview-drawer-header {
padding: 10px; padding: 10px;
} }
.priview-drawer-body { .preview-drawer-body {
padding: 10px; padding: 10px;
height: 100%; height: 100%;
overflow-x: hidden; overflow-x: hidden;
......
...@@ -45,6 +45,7 @@ export default function DigitalHumanDialog({ editor }) { ...@@ -45,6 +45,7 @@ export default function DigitalHumanDialog({ editor }) {
footer={null} footer={null}
width={1600} width={1600}
className='digital-human-modal' className='digital-human-modal'
classNames={{ container: 'digital-human-container', body: 'digital-human-body' }}
centered centered
destroyOnHidden destroyOnHidden
> >
......
...@@ -74,6 +74,10 @@ export default function DigitalHumanFigureField({ figures, loading, value, onCha ...@@ -74,6 +74,10 @@ export default function DigitalHumanFigureField({ figures, loading, value, onCha
onCancel={() => setOpen(false)} onCancel={() => setOpen(false)}
width={920} width={920}
className='digital-human-picker-modal figure-picker-modal' className='digital-human-picker-modal figure-picker-modal'
classNames={{
container: 'digital-human-picker-container',
body: 'digital-human-picker-body figure-picker-body',
}}
> >
{loading && figures.length === 0 ? ( {loading && figures.length === 0 ? (
<div className='picker-loading'> <div className='picker-loading'>
......
...@@ -151,6 +151,10 @@ export default function DigitalHumanVoiceSettings({ ...@@ -151,6 +151,10 @@ export default function DigitalHumanVoiceSettings({
onCancel={() => setOpen(false)} onCancel={() => setOpen(false)}
width={620} width={620}
className='digital-human-picker-modal voice-picker-modal' className='digital-human-picker-modal voice-picker-modal'
classNames={{
container: 'digital-human-picker-container',
body: 'digital-human-picker-body',
}}
> >
<div className='picker-tabs' role='tablist' aria-label='声音性别'> <div className='picker-tabs' role='tablist' aria-label='声音性别'>
<button <button
......
...@@ -8,12 +8,12 @@ ...@@ -8,12 +8,12 @@
--dh-canvas: #f8f6f7; --dh-canvas: #f8f6f7;
max-width: calc(100vw - 24px); max-width: calc(100vw - 24px);
.ant-modal-content { .digital-human-container {
overflow: hidden; overflow: hidden;
border-radius: 10px; border-radius: 10px;
} }
.ant-modal-body { .digital-human-body {
max-height: calc(100vh - 96px); max-height: calc(100vh - 96px);
overflow-y: auto; overflow-y: auto;
overscroll-behavior: contain; overscroll-behavior: contain;
...@@ -988,17 +988,17 @@ ...@@ -988,17 +988,17 @@
} }
.digital-human-picker-modal { .digital-human-picker-modal {
.ant-modal-content { .digital-human-picker-container {
border-radius: 14px; border-radius: 14px;
} }
.ant-modal-body { .digital-human-picker-body {
max-height: 65vh; max-height: 65vh;
overflow-y: auto; overflow-y: auto;
} }
} }
.figure-picker-modal .ant-modal-body { .figure-picker-modal .figure-picker-body {
overflow: hidden; overflow: hidden;
} }
...@@ -1178,7 +1178,7 @@ ...@@ -1178,7 +1178,7 @@
width: calc(100vw - 24px) !important; width: calc(100vw - 24px) !important;
max-width: calc(100vw - 24px); max-width: calc(100vw - 24px);
.ant-modal-body { .digital-human-body {
padding: 12px; padding: 12px;
} }
} }
......
...@@ -19,9 +19,6 @@ const AudioModal = ({ open, onClose, payload = {}, runtime }) => { ...@@ -19,9 +19,6 @@ const AudioModal = ({ open, onClose, payload = {}, runtime }) => {
const fileAccept = ['.mp3', '.wav', '.ogg'] const fileAccept = ['.mp3', '.wav', '.ogg']
const [form] = Form.useForm() const [form] = Form.useForm()
const [uploading, setUploading] = useState(false) // 文件上传状态 const [uploading, setUploading] = useState(false) // 文件上传状态
const [progress, setProgress] = useState(0)
const [file, setFile] = useState({})
const [audioUrl, setAudioUrl] = useState('') const [audioUrl, setAudioUrl] = useState('')
useEffect(() => { useEffect(() => {
...@@ -44,17 +41,21 @@ const AudioModal = ({ open, onClose, payload = {}, runtime }) => { ...@@ -44,17 +41,21 @@ const AudioModal = ({ open, onClose, payload = {}, runtime }) => {
message.error('请上传正确格式的音频文件') message.error('请上传正确格式的音频文件')
return false return false
} }
setProgress(0) return true
setUploading(false)
setFile(file)
}, },
customRequest: async () => { customRequest: async ({ file, onSuccess, onError }) => {
setUploading(true) setUploading(true)
const url = await uploadFile(file) try {
const url = await uploadFile(file)
setAudioUrl(url) setAudioUrl(url)
form.setFieldsValue({ audioUrl: url }) form.setFieldsValue({ audioUrl: url })
setUploading(false) onSuccess?.({ url })
} catch (error) {
message.error('音频上传失败,请重试')
onError?.(error instanceof Error ? error : new Error('音频上传失败'))
} finally {
setUploading(false)
}
}, },
} }
...@@ -80,7 +81,6 @@ const AudioModal = ({ open, onClose, payload = {}, runtime }) => { ...@@ -80,7 +81,6 @@ const AudioModal = ({ open, onClose, payload = {}, runtime }) => {
children: [{ text: '' }], children: [{ text: '' }],
}) })
setAudioUrl('') setAudioUrl('')
setProgress(0)
setUploading(false) setUploading(false)
form.resetFields() form.resetFields()
onClose() onClose()
...@@ -106,7 +106,7 @@ const AudioModal = ({ open, onClose, payload = {}, runtime }) => { ...@@ -106,7 +106,7 @@ const AudioModal = ({ open, onClose, payload = {}, runtime }) => {
<div className='editor-content-form'> <div className='editor-content-form'>
<Form layout='vertical' name='validate_other' form={form} onFinish={onFinish}> <Form layout='vertical' name='validate_other' form={form} onFinish={onFinish}>
<Form.Item label='上传音频' name='audioUrl'> <Form.Item label='上传音频' name='audioUrl'>
<Spin spinning={uploading} description={`${progress}%`}> <Spin spinning={uploading} tip='上传中'>
<div className='editor-dragger'> <div className='editor-dragger'>
<Dragger {...uploadProps} showUploadList={false}> <Dragger {...uploadProps} showUploadList={false}>
{!audioUrl && ( {!audioUrl && (
......
...@@ -35,8 +35,6 @@ const ImageModal = (props, ref) => { ...@@ -35,8 +35,6 @@ const ImageModal = (props, ref) => {
const [bgColorValue, setBgColorValue] = useState('#000000') const [bgColorValue, setBgColorValue] = useState('#000000')
const [textColor, setTextColor] = useState('#ffffff') const [textColor, setTextColor] = useState('#ffffff')
const [uploading, setUploading] = useState(false) // 文件上传状态 const [uploading, setUploading] = useState(false) // 文件上传状态
const [progress, setProgress] = useState(0)
const [file, setFile] = useState({})
const [imgUrl, setImgUrl] = useState('') const [imgUrl, setImgUrl] = useState('')
const [initValues, setInitValues] = useState({ const [initValues, setInitValues] = useState({
title: '', title: '',
...@@ -108,15 +106,21 @@ const ImageModal = (props, ref) => { ...@@ -108,15 +106,21 @@ const ImageModal = (props, ref) => {
message.error('请上传正确格式的图片') message.error('请上传正确格式的图片')
return false return false
} }
setFile(file) return true
}, },
customRequest: async () => { customRequest: async ({ file, onSuccess, onError }) => {
setUploading(true) setUploading(true)
const url = await uploadFile(file) try {
const url = await uploadFile(file)
setImgUrl(url) setImgUrl(url)
form.setFieldsValue({ bgImgUrl: url }) form.setFieldsValue({ bgImgUrl: url })
setUploading(false) onSuccess?.({ url })
} catch (error) {
message.error('图片上传失败,请重试')
onError?.(error instanceof Error ? error : new Error('图片上传失败'))
} finally {
setUploading(false)
}
}, },
} }
...@@ -144,7 +148,6 @@ const ImageModal = (props, ref) => { ...@@ -144,7 +148,6 @@ const ImageModal = (props, ref) => {
if (parseInt(node.random) === parseInt(nowRandom)) { if (parseInt(node.random) === parseInt(nowRandom)) {
SlateTransforms.setNodes(editor, { ...node, ...values }, { at: path }) SlateTransforms.setNodes(editor, { ...node, ...values }, { at: path })
setImgUrl('') setImgUrl('')
setProgress(0)
setUploading(false) setUploading(false)
form.resetFields() form.resetFields()
setTitleVisible(false) setTitleVisible(false)
...@@ -179,7 +182,6 @@ const ImageModal = (props, ref) => { ...@@ -179,7 +182,6 @@ const ImageModal = (props, ref) => {
children: [{ text: '' }], children: [{ text: '' }],
}) })
setImgUrl('') setImgUrl('')
setProgress(0)
setUploading(false) setUploading(false)
form.resetFields() form.resetFields()
setTitleVisible(false) setTitleVisible(false)
...@@ -197,7 +199,7 @@ const ImageModal = (props, ref) => { ...@@ -197,7 +199,7 @@ const ImageModal = (props, ref) => {
initialValues={initValues} initialValues={initValues}
> >
<Form.Item label='章头背景图片' name='bgImgUrl'> <Form.Item label='章头背景图片' name='bgImgUrl'>
<Spin spinning={uploading} description={`${progress}%`}> <Spin spinning={uploading}>
<div className='editor-dragger'> <div className='editor-dragger'>
<Dragger {...uploadProps} showUploadList={false}> <Dragger {...uploadProps} showUploadList={false}>
{!imgUrl && ( {!imgUrl && (
......
import { useState, useEffect, useImperativeHandle, forwardRef } from 'react' import { useState, useEffect, useImperativeHandle, forwardRef } from 'react'
import { CloudUploadOutlined } from '@ant-design/icons' import { CloudUploadOutlined } from '@ant-design/icons'
import { Form, Input, Spin, Upload, Button } from 'antd' import { Form, Input, Spin, Upload, Button, message } from 'antd'
import OnlineImageList from '../../shared/online-image/OnlineImageList' import OnlineImageList from '../../shared/online-image/OnlineImageList'
import { uploadFile } from '@/utils/oss' import { uploadFile } from '@/utils/oss'
...@@ -11,7 +11,6 @@ const GalleryFormItem = (props, ref) => { ...@@ -11,7 +11,6 @@ const GalleryFormItem = (props, ref) => {
const { activeKey, form, setPicList, galleryInfo, isOnline = false } = props const { activeKey, form, setPicList, galleryInfo, isOnline = false } = props
const [uploading, setUploading] = useState(false) // 文件上传状态 const [uploading, setUploading] = useState(false) // 文件上传状态
const [file, setFile] = useState({})
const [imgUrl, setImgUrl] = useState('') const [imgUrl, setImgUrl] = useState('')
useImperativeHandle(ref, () => { useImperativeHandle(ref, () => {
...@@ -59,32 +58,36 @@ const GalleryFormItem = (props, ref) => { ...@@ -59,32 +58,36 @@ const GalleryFormItem = (props, ref) => {
maxCount: 1, maxCount: 1,
showUploadList: false, showUploadList: false,
accept: fileAccept.join(','), accept: fileAccept.join(','),
beforeUpload: (file) => { customRequest: async ({ file, onSuccess, onError }) => {
setFile(file)
},
customRequest: async () => {
setUploading(true) setUploading(true)
const url = await uploadFile(file) try {
const values = { const url = await uploadFile(file)
['content']: { const values = {
[activeKey]: { ['content']: {
url: url, [activeKey]: {
title: '', url: url,
desc: '', title: '',
desc: '',
},
}, },
}, }
} setImgUrl(url)
setImgUrl(url) form.setFieldsValue({ ...values })
form.setFieldsValue({ ...values }) const allContent = form.getFieldValue('content')
const allContent = form.getFieldValue('content') const newGalleryList = []
const newGalleryList = [] // eslint-disable-next-line guard-for-in
// eslint-disable-next-line guard-for-in for (const key in allContent) {
for (const key in allContent) { newGalleryList.push({ ...allContent[key], key: key })
newGalleryList.push({ ...allContent[key], key: key }) }
setPicList(newGalleryList)
form.setFieldsValue({ gallery: newGalleryList })
onSuccess?.({ url })
} catch (error) {
message.error('图片上传失败,请重试')
onError?.(error instanceof Error ? error : new Error('图片上传失败'))
} finally {
setUploading(false)
} }
setPicList(newGalleryList)
form.setFieldsValue({ gallery: newGalleryList })
setUploading(false)
}, },
} }
...@@ -169,7 +172,15 @@ const GalleryFormItem = (props, ref) => { ...@@ -169,7 +172,15 @@ const GalleryFormItem = (props, ref) => {
<img src={imgUrl} alt='' /> <img src={imgUrl} alt='' />
</div> </div>
<div className='editor-uploader-result-tips'> <div className='editor-uploader-result-tips'>
<Button size='small' color='primary' variant='outlined' onClick={() => setImgUrl(null)}> <Button
size='small'
color='primary'
variant='outlined'
onClick={() => {
setImgUrl(null)
form.setFieldValue(['content', activeKey, 'url'], '')
}}
>
替换 替换
</Button> </Button>
</div> </div>
......
...@@ -14,6 +14,7 @@ export default function HistoryFeatureDialog({ open, onClose, runtime }) { ...@@ -14,6 +14,7 @@ export default function HistoryFeatureDialog({ open, onClose, runtime }) {
mask={{ closable: false }} mask={{ closable: false }}
width='90%' width='90%'
onCancel={onClose} onCancel={onClose}
classNames={{ container: 'history-content' }}
wrapClassName='history1' wrapClassName='history1'
style={{ padding: 0 }} style={{ padding: 0 }}
> >
......
...@@ -10,7 +10,7 @@ const HistoryEditor = (props) => { ...@@ -10,7 +10,7 @@ const HistoryEditor = (props) => {
const { setHistoryVisible, chapterId, bookId, setContent, saveContent } = props const { setHistoryVisible, chapterId, bookId, setContent, saveContent } = props
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
const [delMoadal, setDelModal] = useState(false) const [delModal, setDelModal] = useState(false)
const [recordContent, setRecordContent] = useState('') // 内容 const [recordContent, setRecordContent] = useState('') // 内容
const [recordList, setRecordList] = useState([]) // 列表 const [recordList, setRecordList] = useState([]) // 列表
const [recordId, setRecordId] = useState(null) // 当前的记录id const [recordId, setRecordId] = useState(null) // 当前的记录id
...@@ -134,7 +134,8 @@ const HistoryEditor = (props) => { ...@@ -134,7 +134,8 @@ const HistoryEditor = (props) => {
mask={false} mask={false}
centered centered
className='history2' className='history2'
open={delMoadal} classNames={{ container: 'history2-content' }}
open={delModal}
onOk={handleSuccess} onOk={handleSuccess}
onCancel={() => setDelModal(false)} onCancel={() => setDelModal(false)}
footer={(_, { OkBtn, CancelBtn }) => { footer={(_, { OkBtn, CancelBtn }) => {
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
overflow: hidden; overflow: hidden;
} }
.ant-modal, .ant-modal,
.ant-modal-content, .history-content,
.ant-modal-body { .ant-modal-body {
max-height: 90vh; max-height: 90vh;
min-height: 90vh; min-height: 90vh;
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
} }
} }
.history1 { .history1 {
.ant-modal-content { .history-content {
padding: 0; padding: 0;
.history-content-container { .history-content-container {
...@@ -297,7 +297,7 @@ ...@@ -297,7 +297,7 @@
} }
// 画廊展示 // 画廊展示
.gallery-prview-container { .gallery-preview-container {
.gallery-img { .gallery-img {
max-height: 300px; max-height: 300px;
height: 300px; height: 300px;
...@@ -493,7 +493,7 @@ ...@@ -493,7 +493,7 @@
.history2 { .history2 {
z-index: 1000; z-index: 1000;
.ant-modal-content { .history2-content {
padding: 20px; padding: 20px;
} }
} }
...@@ -20,8 +20,6 @@ const ImageModal = (props, ref) => { ...@@ -20,8 +20,6 @@ const ImageModal = (props, ref) => {
const fileAccept = ['.png', '.jpg', '.jpeg', '.svg'] const fileAccept = ['.png', '.jpg', '.jpeg', '.svg']
const [form] = Form.useForm() const [form] = Form.useForm()
const [uploading, setUploading] = useState(false) // 文件上传状态 const [uploading, setUploading] = useState(false) // 文件上传状态
const [progress, setProgress] = useState(0)
const [file, setFile] = useState({})
const [initValues, setInitValues] = useState({ imgUrl: '', imgTitle: '', imgDescript: '' }) const [initValues, setInitValues] = useState({ imgUrl: '', imgTitle: '', imgDescript: '' })
const [tempNodeInfo, setTempNodeInfo] = useState(null) const [tempNodeInfo, setTempNodeInfo] = useState(null)
...@@ -32,7 +30,6 @@ const ImageModal = (props, ref) => { ...@@ -32,7 +30,6 @@ const ImageModal = (props, ref) => {
setInitValues({ imgUrl: image.src, imgTitle: image.alt, imgDescript: image.href }) setInitValues({ imgUrl: image.src, imgTitle: image.alt, imgDescript: image.href })
form.setFieldsValue({ imgUrl: image.src, imgTitle: image.alt, imgDescript: image.href }) form.setFieldsValue({ imgUrl: image.src, imgTitle: image.alt, imgDescript: image.href })
setTempNodeInfo(imageInfo) setTempNodeInfo(imageInfo)
setFile({})
setImageInfo({}) setImageInfo({})
} }
}, [imageInfo]) }, [imageInfo])
...@@ -48,20 +45,26 @@ const ImageModal = (props, ref) => { ...@@ -48,20 +45,26 @@ const ImageModal = (props, ref) => {
message.error('请上传正确格式的图片') message.error('请上传正确格式的图片')
return false return false
} }
setFile(file) return true
}, },
customRequest: async () => { customRequest: async ({ file, onSuccess, onError }) => {
setUploading(true) setUploading(true)
const url = await uploadFile(file) try {
setImgUrl(url) const url = await uploadFile(file)
form.setFieldsValue({ imgUrl: url }) setImgUrl(url)
setUploading(false) form.setFieldsValue({ imgUrl: url })
onSuccess?.({ url })
} catch (error) {
message.error('图片上传失败,请重试')
onError?.(error instanceof Error ? error : new Error('图片上传失败'))
} finally {
setUploading(false)
}
}, },
} }
const clear = () => { const clear = () => {
setImgUrl('') setImgUrl('')
setProgress(0)
setUploading(false) setUploading(false)
setTempNodeInfo(null) setTempNodeInfo(null)
setInitValues({ imgUrl: imgUrl, imgTitle: '', imgDescript: '' }) setInitValues({ imgUrl: imgUrl, imgTitle: '', imgDescript: '' })
...@@ -158,7 +161,7 @@ const ImageModal = (props, ref) => { ...@@ -158,7 +161,7 @@ const ImageModal = (props, ref) => {
name='imgUrl' name='imgUrl'
rules={[{ required: true, message: '请上传图片' }]} rules={[{ required: true, message: '请上传图片' }]}
> >
<Spin spinning={uploading} description={`${progress}%`}> <Spin spinning={uploading}>
<div className='editor-dragger'> <div className='editor-dragger'>
<Dragger {...uploadProps} showUploadList={false}> <Dragger {...uploadProps} showUploadList={false}>
{!imgUrl && ( {!imgUrl && (
...@@ -178,7 +181,15 @@ const ImageModal = (props, ref) => { ...@@ -178,7 +181,15 @@ const ImageModal = (props, ref) => {
<img src={imgUrl} alt='' /> <img src={imgUrl} alt='' />
</div> </div>
<div className='editor-uploader-result-tips'> <div className='editor-uploader-result-tips'>
<Button size='small' color='primary' variant='outlined' onClick={() => setImgUrl(null)}> <Button
size='small'
color='primary'
variant='outlined'
onClick={() => {
setImgUrl(null)
form.setFieldsValue({ imgUrl: '' })
}}
>
替换 替换
</Button> </Button>
</div> </div>
......
...@@ -54,6 +54,7 @@ export function PracticeSettingsFeatureDialog({ open, onClose, payload, runtime ...@@ -54,6 +54,7 @@ export function PracticeSettingsFeatureDialog({ open, onClose, payload, runtime
header: 'practice-topic-header', header: 'practice-topic-header',
body: 'practice-topic-content', body: 'practice-topic-content',
wrapper: 'practice-topic-modal', wrapper: 'practice-topic-modal',
container: 'practice-topic-container',
}} }}
mask={{ closable: false }} mask={{ closable: false }}
closeIcon={false} closeIcon={false}
......
...@@ -5,7 +5,7 @@ import { useEditorStore } from '@/stores/editorStore' ...@@ -5,7 +5,7 @@ import { useEditorStore } from '@/stores/editorStore'
import TopicItem from './topicItem' import TopicItem from './topicItem'
import { addChapterTopic, getChapterTopic } from '../../../shared/request' import { addChapterTopic, getChapterTopic } from '../../../shared/request'
import { clacTopicText } from '@/utils/common' import { calcTopicText } from '@/utils/common'
const InsertTopic = (props, ref) => { const InsertTopic = (props, ref) => {
const { const {
...@@ -77,7 +77,7 @@ const InsertTopic = (props, ref) => { ...@@ -77,7 +77,7 @@ const InsertTopic = (props, ref) => {
<div className='practice-insert-topic list-topic-box'> <div className='practice-insert-topic list-topic-box'>
{radioList.length > 0 && ( {radioList.length > 0 && (
<div className='list-topic-container'> <div className='list-topic-container'>
<h4>{clacTopicText('radio')}. 单选题</h4> <h4>{calcTopicText('radio')}. 单选题</h4>
<div> <div>
{radioList.map((item, index) => { {radioList.map((item, index) => {
return ( return (
...@@ -108,7 +108,7 @@ const InsertTopic = (props, ref) => { ...@@ -108,7 +108,7 @@ const InsertTopic = (props, ref) => {
{checkboxList.length > 0 && ( {checkboxList.length > 0 && (
<div className='list-topic-container'> <div className='list-topic-container'>
<h4>{clacTopicText('checkbox', radioList)}. 多选题</h4> <h4>{calcTopicText('checkbox', radioList)}. 多选题</h4>
<div> <div>
{checkboxList.map((item, index) => { {checkboxList.map((item, index) => {
return ( return (
...@@ -138,7 +138,7 @@ const InsertTopic = (props, ref) => { ...@@ -138,7 +138,7 @@ const InsertTopic = (props, ref) => {
)} )}
{equalsList.length > 0 && ( {equalsList.length > 0 && (
<div className='list-topic-container'> <div className='list-topic-container'>
<h4>{clacTopicText('judge', radioList, checkboxList)}. 判断题</h4> <h4>{calcTopicText('judge', radioList, checkboxList)}. 判断题</h4>
<div> <div>
{equalsList.map((item, index) => { {equalsList.map((item, index) => {
return ( return (
...@@ -168,7 +168,7 @@ const InsertTopic = (props, ref) => { ...@@ -168,7 +168,7 @@ const InsertTopic = (props, ref) => {
)} )}
{pressList.length > 0 && ( {pressList.length > 0 && (
<div className='list-topic-container'> <div className='list-topic-container'>
<h4>{clacTopicText('fill', radioList, checkboxList, equalsList)}. 填空题</h4> <h4>{calcTopicText('fill', radioList, checkboxList, equalsList)}. 填空题</h4>
<div> <div>
{pressList.map((item, index) => { {pressList.map((item, index) => {
return ( return (
...@@ -199,7 +199,7 @@ const InsertTopic = (props, ref) => { ...@@ -199,7 +199,7 @@ const InsertTopic = (props, ref) => {
{textareaList.length > 0 && ( {textareaList.length > 0 && (
<div className='list-topic-container'> <div className='list-topic-container'>
<h4> <h4>
{clacTopicText('textarea', radioList, checkboxList, equalsList, pressList)}. 简答题 {calcTopicText('textarea', radioList, checkboxList, equalsList, pressList)}. 简答题
</h4> </h4>
<div> <div>
{textareaList.map((item, index) => { {textareaList.map((item, index) => {
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
inset-inline-end: 17px; inset-inline-end: 17px;
top: 16px; top: 16px;
} }
.ant-modal-content { .practice-topic-container {
padding: 15px 18px; padding: 15px 18px;
} }
.ant-divider { .ant-divider {
......
...@@ -13,7 +13,12 @@ export default function PreviewFeatureDialog({ open, onClose, runtime }) { ...@@ -13,7 +13,12 @@ export default function PreviewFeatureDialog({ open, onClose, runtime }) {
keyboard={false} keyboard={false}
closeIcon={<CloseOutlined style={{ fontSize: 20, color: '#fff' }} />} closeIcon={<CloseOutlined style={{ fontSize: 20, color: '#fff' }} />}
mask={{ closable: false }} mask={{ closable: false }}
classNames={{ body: 'phone-body', wrapper: 'phone-wrapper' }} classNames={{
container: 'phone-content',
body: 'phone-body',
wrapper: 'phone-wrapper',
close: 'phone-close',
}}
wrapClassName='wrap-phone-privew' wrapClassName='wrap-phone-privew'
width='494px' width='494px'
onCancel={onClose} onCancel={onClose}
......
...@@ -9,7 +9,7 @@ import { getChapterTopic, expandReadInfo } from '../../shared/request' ...@@ -9,7 +9,7 @@ import { getChapterTopic, expandReadInfo } from '../../shared/request'
import TopicItem from '../practice/components/topicItem' import TopicItem from '../practice/components/topicItem'
import '@/components/editor/preview.less' import '@/components/editor/preview.less'
import { clacTopicText } from '@/utils/common' import { calcTopicText } from '@/utils/common'
import hljs from 'highlight.js' import hljs from 'highlight.js'
import 'highlight.js/styles/github.css' import 'highlight.js/styles/github.css'
...@@ -46,7 +46,7 @@ const correctList = [ ...@@ -46,7 +46,7 @@ const correctList = [
const PreviewScreen = (props, ref) => { const PreviewScreen = (props, ref) => {
const { editor, bookId, chapterId, gData, nowTitle } = props const { editor, bookId, chapterId, gData, nowTitle } = props
const [loading, setLoading] = useState(false) // 展示 const [loading, setLoading] = useState(false) // 展示
const [prviewHtml, setPrviewHtml] = useState('') // 预览html const [previewHtml, setPrviewHtml] = useState('') // 预览html
const [open, setOpen] = useState(false) // 抽屉 const [open, setOpen] = useState(false) // 抽屉
const [toolTip, setTooltip] = useState({}) const [toolTip, setTooltip] = useState({})
...@@ -114,12 +114,15 @@ const PreviewScreen = (props, ref) => { ...@@ -114,12 +114,15 @@ const PreviewScreen = (props, ref) => {
} }
const handlerClick = () => { const handlerClick = () => {
const eventNamespace = '.editorPreview'
const previewContent = $('.preview-content-html')
const secondaryContent = $('.expand-content, .gallery-preview-container')
const iParentW = $('.preview-content-it').innerWidth() const iParentW = $('.preview-content-it').innerWidth()
const iParentH = $('.preview-content-it').innerHeight() const iParentH = $('.preview-content-it').innerHeight()
const parentOffset = $('.preview-content-it').offset() // 获取父元素相对于文档的位置 const parentOffset = $('.preview-content-it').offset() // 获取父元素相对于文档的位置
const parentRect = $('.preview-content-it')[0].getBoundingClientRect() // 获取父元素相对于文档的位置 const parentRect = $('.preview-content-it')[0].getBoundingClientRect() // 获取父元素相对于文档的位置
$('.preview-content-html').on('click', (ev) => { previewContent.off(eventNamespace).on(`click${eventNamespace}`, (ev) => {
ev.stopPropagation() ev.stopPropagation()
const target = ev.target const target = ev.target
...@@ -326,7 +329,7 @@ const PreviewScreen = (props, ref) => { ...@@ -326,7 +329,7 @@ const PreviewScreen = (props, ref) => {
setGallery([]) setGallery([])
}) })
$('.expand-content, .gallery-prview-container').on('click', (ev) => { secondaryContent.off(eventNamespace).on(`click${eventNamespace}`, (ev) => {
const target = ev.target const target = ev.target
if (target.nodeName.toLowerCase() === 'img') { if (target.nodeName.toLowerCase() === 'img') {
...@@ -338,10 +341,15 @@ const PreviewScreen = (props, ref) => { ...@@ -338,10 +341,15 @@ const PreviewScreen = (props, ref) => {
setSecondType('扩展图片') setSecondType('扩展图片')
} }
}) })
return () => {
previewContent.off(eventNamespace)
secondaryContent.off(eventNamespace)
}
} }
useEffect(() => { useEffect(() => {
handlerClick() return handlerClick()
}, []) }, [])
const getChapterId = async () => { const getChapterId = async () => {
...@@ -356,7 +364,7 @@ const PreviewScreen = (props, ref) => { ...@@ -356,7 +364,7 @@ const PreviewScreen = (props, ref) => {
if (data) { if (data) {
const content = get(data, 'content', '') const content = get(data, 'content', '')
setPrviewHtml(content) setPrviewHtml(content)
$('#previee-container') $('#preview-container')
.find('video audio') .find('video audio')
.each((index, item) => { .each((index, item) => {
$(item).attr('controls', true).attr('controlslist', 'nodownload') $(item).attr('controls', true).attr('controlslist', 'nodownload')
...@@ -383,7 +391,7 @@ const PreviewScreen = (props, ref) => { ...@@ -383,7 +391,7 @@ const PreviewScreen = (props, ref) => {
// if (data) { // if (data) {
// const content = get(data, 'content', ''); // const content = get(data, 'content', '');
// setPrviewHtml(content); // setPrviewHtml(content);
// $('#previee-container') // $('#preview-container')
// .find('video audio') // .find('video audio')
// .each((index, item) => { // .each((index, item) => {
// $(item).attr('controls', true); // $(item).attr('controls', true);
...@@ -417,8 +425,8 @@ const PreviewScreen = (props, ref) => { ...@@ -417,8 +425,8 @@ const PreviewScreen = (props, ref) => {
} }
return ( return (
<div className='priview-modal'> <div className='preview-modal'>
<div className='previee-container' id='previee-container'> <div className='preview-container' id='preview-container'>
<div className='chapter-head-title'> <div className='chapter-head-title'>
<h2> <h2>
{opend ? ( {opend ? (
...@@ -456,14 +464,14 @@ const PreviewScreen = (props, ref) => { ...@@ -456,14 +464,14 @@ const PreviewScreen = (props, ref) => {
<Spin spinning={loading} classNames={{ root: 'chapter-loading' }}> <Spin spinning={loading} classNames={{ root: 'chapter-loading' }}>
<div <div
className='preview-content-html' className='preview-content-html'
dangerouslySetInnerHTML={{ __html: prviewHtml }} dangerouslySetInnerHTML={{ __html: previewHtml }}
></div> ></div>
</Spin> </Spin>
</div> </div>
{isType && ( {isType && (
<div className='preview-content-other'> <div className='preview-content-other'>
{isType === 'gallery' && ( {isType === 'gallery' && (
<div className='gallery-prview-container'> <div className='gallery-preview-container'>
{gallery && gallery.length > 0 ? ( {gallery && gallery.length > 0 ? (
<> <>
<div className='gallery-img'> <div className='gallery-img'>
...@@ -491,7 +499,7 @@ const PreviewScreen = (props, ref) => { ...@@ -491,7 +499,7 @@ const PreviewScreen = (props, ref) => {
<div className='practice-insert-topic'> <div className='practice-insert-topic'>
{radioList.length > 0 && ( {radioList.length > 0 && (
<div className='topic_style'> <div className='topic_style'>
<h3>{clacTopicText('radio')}. 单选题</h3> <h3>{calcTopicText('radio')}. 单选题</h3>
<div className='practice-list'> <div className='practice-list'>
{radioList.map((item, index) => { {radioList.map((item, index) => {
return ( return (
...@@ -540,7 +548,7 @@ const PreviewScreen = (props, ref) => { ...@@ -540,7 +548,7 @@ const PreviewScreen = (props, ref) => {
)} )}
{checkBoxList.length > 0 && ( {checkBoxList.length > 0 && (
<div className='topic_style'> <div className='topic_style'>
<h3>{clacTopicText('checkbox', radioList)}. 多选题</h3> <h3>{calcTopicText('checkbox', radioList)}. 多选题</h3>
<div className='practice-list'> <div className='practice-list'>
{checkBoxList.map((item, index) => { {checkBoxList.map((item, index) => {
return ( return (
...@@ -589,7 +597,7 @@ const PreviewScreen = (props, ref) => { ...@@ -589,7 +597,7 @@ const PreviewScreen = (props, ref) => {
)} )}
{judgeList.length > 0 && ( {judgeList.length > 0 && (
<div className='topic_style'> <div className='topic_style'>
<h3>{clacTopicText('judge', radioList, checkBoxList)}. 判断题</h3> <h3>{calcTopicText('judge', radioList, checkBoxList)}. 判断题</h3>
<div className='practice-list'> <div className='practice-list'>
{judgeList.map((item, index) => { {judgeList.map((item, index) => {
return ( return (
...@@ -638,7 +646,7 @@ const PreviewScreen = (props, ref) => { ...@@ -638,7 +646,7 @@ const PreviewScreen = (props, ref) => {
)} )}
{fillList.length > 0 && ( {fillList.length > 0 && (
<div className='topic_style'> <div className='topic_style'>
<h3>{clacTopicText('fill', radioList, checkBoxList, judgeList)}. 填空题</h3> <h3>{calcTopicText('fill', radioList, checkBoxList, judgeList)}. 填空题</h3>
<div className='practice-list'> <div className='practice-list'>
{fillList.map((item, index) => { {fillList.map((item, index) => {
return ( return (
...@@ -688,7 +696,7 @@ const PreviewScreen = (props, ref) => { ...@@ -688,7 +696,7 @@ const PreviewScreen = (props, ref) => {
{textareaList.length > 0 && ( {textareaList.length > 0 && (
<div className='topic_style'> <div className='topic_style'>
<h3> <h3>
{clacTopicText('textarea', radioList, checkBoxList, judgeList, fillList)}. {calcTopicText('textarea', radioList, checkBoxList, judgeList, fillList)}.
简答题 简答题
</h3> </h3>
<div className='practice-list'> <div className='practice-list'>
...@@ -786,10 +794,10 @@ const PreviewScreen = (props, ref) => { ...@@ -786,10 +794,10 @@ const PreviewScreen = (props, ref) => {
open={open} open={open}
getContainer={false} getContainer={false}
placement='left' placement='left'
classNames={{ header: 'priview-drawer-header', body: 'priview-drawer-body' }} classNames={{ header: 'preview-drawer-header', body: 'preview-drawer-body' }}
width='200' width='200'
title='章节目录' title='章节目录'
rootClassName='priview-drawer-container' rootClassName='preview-drawer-container'
> >
<Tree <Tree
className='draggable-tree' className='draggable-tree'
......
...@@ -20,9 +20,6 @@ const VideoModal = ({ open, onClose, payload = {}, runtime }) => { ...@@ -20,9 +20,6 @@ const VideoModal = ({ open, onClose, payload = {}, runtime }) => {
const fileAccept = ['.ogg', '.mp4', '.webm'] const fileAccept = ['.ogg', '.mp4', '.webm']
const [form] = Form.useForm() const [form] = Form.useForm()
const [uploading, setUploading] = useState(false) // 文件上传状态 const [uploading, setUploading] = useState(false) // 文件上传状态
const [progress, setProgress] = useState(0)
const [file, setFile] = useState({})
const [videoUrl, setVideoUrl] = useState('') const [videoUrl, setVideoUrl] = useState('')
useEffect(() => { useEffect(() => {
...@@ -45,16 +42,21 @@ const VideoModal = ({ open, onClose, payload = {}, runtime }) => { ...@@ -45,16 +42,21 @@ const VideoModal = ({ open, onClose, payload = {}, runtime }) => {
message.error('请上传正确格式的视频') message.error('请上传正确格式的视频')
return false return false
} }
setProgress(0) return true
setUploading(false)
setFile(file)
}, },
customRequest: async () => { customRequest: async ({ file, onSuccess, onError }) => {
setUploading(true) setUploading(true)
const url = await uploadFile(file) try {
setVideoUrl(url) const url = await uploadFile(file)
form.setFieldsValue({ videoUrl: url }) setVideoUrl(url)
setUploading(false) form.setFieldsValue({ videoUrl: url })
onSuccess?.({ url })
} catch (error) {
message.error('视频上传失败,请重试')
onError?.(error instanceof Error ? error : new Error('视频上传失败'))
} finally {
setUploading(false)
}
}, },
} }
...@@ -81,7 +83,6 @@ const VideoModal = ({ open, onClose, payload = {}, runtime }) => { ...@@ -81,7 +83,6 @@ const VideoModal = ({ open, onClose, payload = {}, runtime }) => {
}) })
setVideoUrl('') setVideoUrl('')
setProgress(0)
setUploading(false) setUploading(false)
form.resetFields() form.resetFields()
onClose() onClose()
...@@ -111,7 +112,7 @@ const VideoModal = ({ open, onClose, payload = {}, runtime }) => { ...@@ -111,7 +112,7 @@ const VideoModal = ({ open, onClose, payload = {}, runtime }) => {
name='videoUrl' name='videoUrl'
rules={[{ required: true, message: '请上传视频' }]} rules={[{ required: true, message: '请上传视频' }]}
> >
<Spin spinning={uploading} description={`${progress}%`}> <Spin spinning={uploading} tip='上传中'>
<div className='editor-dragger'> <div className='editor-dragger'>
<Dragger {...uploadProps} showUploadList={false}> <Dragger {...uploadProps} showUploadList={false}>
{!videoUrl && ( {!videoUrl && (
......
...@@ -131,11 +131,9 @@ export function usePagedList<Row, Filters, Query>({ ...@@ -131,11 +131,9 @@ export function usePagedList<Row, Filters, Query>({
}, [initialFilters, initialPage, loadFor, state.pageSize]) }, [initialFilters, initialPage, loadFor, state.pageSize])
const refresh = useCallback(() => { const refresh = useCallback(() => {
if (useAppliedFilters) { const filters = useAppliedFilters ? state.appliedFilters : state.filters
setState((current) => ({ ...current, appliedFilters: state.filters })) void loadFor(state.page, state.pageSize, filters)
} }, [loadFor, state.appliedFilters, state.filters, state.page, state.pageSize, useAppliedFilters])
void loadFor(state.page, state.pageSize, state.filters)
}, [loadFor, state.filters, state.page, state.pageSize, useAppliedFilters])
const refreshUnfiltered = useCallback(() => { const refreshUnfiltered = useCallback(() => {
void loadFor(state.page, state.pageSize, initialFilters) void loadFor(state.page, state.pageSize, initialFilters)
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
} }
.audit-preview-tree, .audit-preview-tree,
.previee-container { .preview-container {
height: 100%; height: 100%;
min-width: 0; min-width: 0;
border: 0; border: 0;
...@@ -94,13 +94,13 @@ ...@@ -94,13 +94,13 @@
} }
} }
.previee-container { .preview-container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
border-radius: 0; border-radius: 0;
} }
&.wrap-phone-privew .previee-container .chapter-head-title { &.wrap-phone-privew .preview-container .chapter-head-title {
flex: 0 0 var(--audit-review-header-height); flex: 0 0 var(--audit-review-header-height);
height: var(--audit-review-header-height); height: var(--audit-review-header-height);
line-height: var(--audit-review-header-height); line-height: var(--audit-review-header-height);
...@@ -528,7 +528,7 @@ ...@@ -528,7 +528,7 @@
.audit-review-preview { .audit-review-preview {
.audit-preview-tree, .audit-preview-tree,
.previee-container { .preview-container {
height: 360px; height: 360px;
} }
} }
......
...@@ -15,7 +15,7 @@ import { ...@@ -15,7 +15,7 @@ import {
convertToAntdTreeData, convertToAntdTreeData,
findTreeElementByKey, findTreeElementByKey,
findFirstNotHasChildren, findFirstNotHasChildren,
clacTopicText, calcTopicText,
} from '@/utils/common' } from '@/utils/common'
import { findReviewCommentRange, useReviewHighlights } from '../../review-comments/highlights' import { findReviewCommentRange, useReviewHighlights } from '../../review-comments/highlights'
import { get } from 'lodash-es' import { get } from 'lodash-es'
...@@ -86,7 +86,7 @@ const PreviewScreen = (props, ref) => { ...@@ -86,7 +86,7 @@ const PreviewScreen = (props, ref) => {
} = props } = props
const [gData, setGData] = useState([]) const [gData, setGData] = useState([])
const [loading, setLoading] = useState(false) // 展示 const [loading, setLoading] = useState(false) // 展示
const [prviewHtml, setPrviewHtml] = useState('') // 预览html const [previewHtml, setPrviewHtml] = useState('') // 预览html
const [open, setOpen] = useState(false) // 抽屉 const [open, setOpen] = useState(false) // 抽屉
const [secondType, setSecondType] = useState(false) const [secondType, setSecondType] = useState(false)
const [pageMap, setPageMap] = useState({}) // 叶子节点页码映射 const [pageMap, setPageMap] = useState({}) // 叶子节点页码映射
...@@ -118,9 +118,9 @@ const PreviewScreen = (props, ref) => { ...@@ -118,9 +118,9 @@ const PreviewScreen = (props, ref) => {
const previewContentRef = useRef(null) const previewContentRef = useRef(null)
const previewText = useMemo(() => { const previewText = useMemo(() => {
const element = document.createElement('div') const element = document.createElement('div')
element.innerHTML = prviewHtml || '' element.innerHTML = previewHtml || ''
return element.textContent || '' return element.textContent || ''
}, [prviewHtml]) }, [previewHtml])
const getPreviewRoot = useCallback(() => previewContentRef.current || undefined, []) const getPreviewRoot = useCallback(() => previewContentRef.current || undefined, [])
useReviewHighlights({ useReviewHighlights({
...@@ -130,7 +130,7 @@ const PreviewScreen = (props, ref) => { ...@@ -130,7 +130,7 @@ const PreviewScreen = (props, ref) => {
draftAnchor: draftCommentAnchor, draftAnchor: draftCommentAnchor,
activeCommentId, activeCommentId,
enabled: true, enabled: true,
rootVersion: prviewHtml, rootVersion: previewHtml,
}) })
// 递归函数,获取所有节点的key // 递归函数,获取所有节点的key
...@@ -225,7 +225,7 @@ const PreviewScreen = (props, ref) => { ...@@ -225,7 +225,7 @@ const PreviewScreen = (props, ref) => {
content, content,
text: contentElement.textContent || '', text: contentElement.textContent || '',
}) })
$('#previee-container') $('#preview-container')
.find('video audio') .find('video audio')
.each((index, item) => { .each((index, item) => {
$(item).attr('controls', true).attr('controlslist', 'nodownload') $(item).attr('controls', true).attr('controlslist', 'nodownload')
...@@ -244,12 +244,15 @@ const PreviewScreen = (props, ref) => { ...@@ -244,12 +244,15 @@ const PreviewScreen = (props, ref) => {
} }
const handlerClick = () => { const handlerClick = () => {
const eventNamespace = '.auditPreview'
const previewContent = $('.preview-content-html')
const secondaryContent = $('.expand-content, .gallery-preview-container')
const iParentW = $('.preview-content-it').innerWidth() const iParentW = $('.preview-content-it').innerWidth()
const iParentH = $('.preview-content-it').innerHeight() const iParentH = $('.preview-content-it').innerHeight()
const parentOffset = $('.preview-content-it').offset() // 获取父元素相对于文档的位置 const parentOffset = $('.preview-content-it').offset() // 获取父元素相对于文档的位置
const parentRect = $('.preview-content-it')[0].getBoundingClientRect() // 获取父元素相对于文档的位置 const parentRect = $('.preview-content-it')[0].getBoundingClientRect() // 获取父元素相对于文档的位置
$('.preview-content-html').on('click', async (ev) => { previewContent.off(eventNamespace).on(`click${eventNamespace}`, async (ev) => {
ev.stopPropagation() ev.stopPropagation()
const target = ev.target const target = ev.target
...@@ -455,7 +458,7 @@ const PreviewScreen = (props, ref) => { ...@@ -455,7 +458,7 @@ const PreviewScreen = (props, ref) => {
setGallery([]) setGallery([])
}) })
$('.expand-content, .gallery-prview-container').on('click', (ev) => { secondaryContent.off(eventNamespace).on(`click${eventNamespace}`, (ev) => {
const target = ev.target const target = ev.target
if (target.nodeName.toLowerCase() === 'img') { if (target.nodeName.toLowerCase() === 'img') {
...@@ -467,10 +470,15 @@ const PreviewScreen = (props, ref) => { ...@@ -467,10 +470,15 @@ const PreviewScreen = (props, ref) => {
setSecondType('扩展图片') setSecondType('扩展图片')
} }
}) })
return () => {
previewContent.off(eventNamespace)
secondaryContent.off(eventNamespace)
}
} }
useEffect(() => { useEffect(() => {
handlerClick() return handlerClick()
}, [isType]) }, [isType])
useEffect(() => { useEffect(() => {
...@@ -594,7 +602,7 @@ const PreviewScreen = (props, ref) => { ...@@ -594,7 +602,7 @@ const PreviewScreen = (props, ref) => {
) )
return ( return (
<div className={`priview-modal${desktop ? ' desktop-preview' : ''}`}> <div className={`preview-modal${desktop ? ' desktop-preview' : ''}`}>
{/* <Spin spinning={loading}> */} {/* <Spin spinning={loading}> */}
{desktop && ( {desktop && (
<aside <aside
...@@ -613,7 +621,7 @@ const PreviewScreen = (props, ref) => { ...@@ -613,7 +621,7 @@ const PreviewScreen = (props, ref) => {
{!treeCollapsed && renderChapterTree()} {!treeCollapsed && renderChapterTree()}
</aside> </aside>
)} )}
<div className='previee-container' id='previee-container'> <div className='preview-container' id='preview-container'>
<div className='chapter-head-title'> <div className='chapter-head-title'>
<h2 className='tree'> <h2 className='tree'>
{opend ? ( {opend ? (
...@@ -658,7 +666,7 @@ const PreviewScreen = (props, ref) => { ...@@ -658,7 +666,7 @@ const PreviewScreen = (props, ref) => {
<div <div
ref={previewContentRef} ref={previewContentRef}
className='preview-content-html' className='preview-content-html'
dangerouslySetInnerHTML={{ __html: prviewHtml }} dangerouslySetInnerHTML={{ __html: previewHtml }}
onMouseDown={() => { onMouseDown={() => {
onTextSelection?.(null) onTextSelection?.(null)
}} }}
...@@ -676,7 +684,7 @@ const PreviewScreen = (props, ref) => { ...@@ -676,7 +684,7 @@ const PreviewScreen = (props, ref) => {
{isType && ( {isType && (
<div className='preview-content-other'> <div className='preview-content-other'>
{isType === 'gallery' && ( {isType === 'gallery' && (
<div className='gallery-prview-container'> <div className='gallery-preview-container'>
{gallery && gallery.length > 0 ? ( {gallery && gallery.length > 0 ? (
<> <>
<div className='gallery-img'> <div className='gallery-img'>
...@@ -704,7 +712,7 @@ const PreviewScreen = (props, ref) => { ...@@ -704,7 +712,7 @@ const PreviewScreen = (props, ref) => {
<div className='practice-insert-topic'> <div className='practice-insert-topic'>
{radioList.length > 0 && ( {radioList.length > 0 && (
<div className='topic_style'> <div className='topic_style'>
<h3>{clacTopicText('radio')}. 单选题</h3> <h3>{calcTopicText('radio')}. 单选题</h3>
<div className='practice-list'> <div className='practice-list'>
{radioList.map((item, index) => { {radioList.map((item, index) => {
return ( return (
...@@ -753,7 +761,7 @@ const PreviewScreen = (props, ref) => { ...@@ -753,7 +761,7 @@ const PreviewScreen = (props, ref) => {
)} )}
{checkBoxList.length > 0 && ( {checkBoxList.length > 0 && (
<div className='topic_style'> <div className='topic_style'>
<h3>{clacTopicText('checkbox', radioList)}. 多选题</h3> <h3>{calcTopicText('checkbox', radioList)}. 多选题</h3>
<div className='practice-list'> <div className='practice-list'>
{checkBoxList.map((item, index) => { {checkBoxList.map((item, index) => {
return ( return (
...@@ -802,7 +810,7 @@ const PreviewScreen = (props, ref) => { ...@@ -802,7 +810,7 @@ const PreviewScreen = (props, ref) => {
)} )}
{judgeList.length > 0 && ( {judgeList.length > 0 && (
<div className='topic_style'> <div className='topic_style'>
<h3>{clacTopicText('judge', radioList, checkBoxList)}. 判断题</h3> <h3>{calcTopicText('judge', radioList, checkBoxList)}. 判断题</h3>
<div className='practice-list'> <div className='practice-list'>
{judgeList.map((item, index) => { {judgeList.map((item, index) => {
return ( return (
...@@ -851,7 +859,7 @@ const PreviewScreen = (props, ref) => { ...@@ -851,7 +859,7 @@ const PreviewScreen = (props, ref) => {
)} )}
{fillList.length > 0 && ( {fillList.length > 0 && (
<div className='topic_style'> <div className='topic_style'>
<h3>{clacTopicText('fill', radioList, checkBoxList, judgeList)}. 填空题</h3> <h3>{calcTopicText('fill', radioList, checkBoxList, judgeList)}. 填空题</h3>
<div className='practice-list'> <div className='practice-list'>
{fillList.map((item, index) => { {fillList.map((item, index) => {
return ( return (
...@@ -901,7 +909,7 @@ const PreviewScreen = (props, ref) => { ...@@ -901,7 +909,7 @@ const PreviewScreen = (props, ref) => {
{textareaList.length > 0 && ( {textareaList.length > 0 && (
<div className='topic_style'> <div className='topic_style'>
<h3> <h3>
{clacTopicText('textarea', radioList, checkBoxList, judgeList, fillList)}. {calcTopicText('textarea', radioList, checkBoxList, judgeList, fillList)}.
简答题 简答题
</h3> </h3>
<div className='practice-list'> <div className='practice-list'>
...@@ -1007,10 +1015,10 @@ const PreviewScreen = (props, ref) => { ...@@ -1007,10 +1015,10 @@ const PreviewScreen = (props, ref) => {
open={open} open={open}
getContainer={false} getContainer={false}
placement='left' placement='left'
classNames={{ header: 'priview-drawer-header', body: 'priview-drawer-body' }} classNames={{ header: 'preview-drawer-header', body: 'preview-drawer-body' }}
size={300} size={300}
title='章节目录' title='章节目录'
rootClassName='priview-drawer-container' rootClassName='preview-drawer-container'
> >
{renderChapterTree()} {renderChapterTree()}
</Drawer> </Drawer>
......
...@@ -586,6 +586,7 @@ const Examine = () => { ...@@ -586,6 +586,7 @@ const Examine = () => {
onCancel={() => setEditKey(false)} onCancel={() => setEditKey(false)}
classNames={{ classNames={{
wrapper: 'chapter-title-modal', wrapper: 'chapter-title-modal',
container: 'chapter-title-container',
}} }}
> >
<EditChapterTitle <EditChapterTitle
......
...@@ -123,7 +123,7 @@ ...@@ -123,7 +123,7 @@
inset-inline-end: 17px; inset-inline-end: 17px;
top: 16px; top: 16px;
} }
.ant-modal-content { .chapter-title-container {
padding: 15px 18px; padding: 15px 18px;
} }
.ant-divider { .ant-divider {
......
...@@ -8,7 +8,7 @@ import { getCommentInfo, commentReply, commentDel } from '../api' ...@@ -8,7 +8,7 @@ import { getCommentInfo, commentReply, commentDel } from '../api'
const { TextArea } = Input const { TextArea } = Input
const DiscussDetail = () => { const DiscussDetail = () => {
const [showReply, setShowReply] = useState(false) const [showReply, setShowReply] = useState(false)
const [delMoadal, setDelModal] = useState(false) const [delModal, setDelModal] = useState(false)
const [searchParams] = useSearchParams() const [searchParams] = useSearchParams()
const id = Number(searchParams.get('id')) const id = Number(searchParams.get('id'))
const name = searchParams.get('book_name') || '' const name = searchParams.get('book_name') || ''
...@@ -97,7 +97,7 @@ const DiscussDetail = () => { ...@@ -97,7 +97,7 @@ const DiscussDetail = () => {
<Modal <Modal
mask={false} mask={false}
centered centered
open={delMoadal} open={delModal}
onOk={handleDel} onOk={handleDel}
onCancel={() => setDelModal(false)} onCancel={() => setDelModal(false)}
footer={(_, { OkBtn, CancelBtn }) => { footer={(_, { OkBtn, CancelBtn }) => {
......
...@@ -37,7 +37,7 @@ const AppVersion = () => { ...@@ -37,7 +37,7 @@ const AppVersion = () => {
changePageSize, changePageSize,
} = useAppVersionList() } = useAppVersionList()
const [isEdit, setIsEdit] = useState(false) const [isEdit, setIsEdit] = useState(false)
const [delMoadal, setDelModal] = useState(false) const [delModal, setDelModal] = useState(false)
const [isadd, setisadd] = useState(true) const [isadd, setisadd] = useState(true)
const [form] = Form.useForm() const [form] = Form.useForm()
const checkPermission = usePermission() const checkPermission = usePermission()
...@@ -264,7 +264,7 @@ const AppVersion = () => { ...@@ -264,7 +264,7 @@ const AppVersion = () => {
<Modal <Modal
mask={false} mask={false}
centered centered
open={delMoadal} open={delModal}
onOk={handleDel} onOk={handleDel}
onCancel={() => setDelModal(false)} onCancel={() => setDelModal(false)}
footer={(_, { OkBtn, CancelBtn }) => { footer={(_, { OkBtn, CancelBtn }) => {
......
...@@ -86,7 +86,7 @@ ...@@ -86,7 +86,7 @@
inset-inline-end: 17px; inset-inline-end: 17px;
top: 16px; top: 16px;
} }
.ant-modal-content { .chapter-title-container {
padding: 15px 18px; padding: 15px 18px;
} }
.ant-divider { .ant-divider {
......
...@@ -180,7 +180,7 @@ export const hexToRgb = (hex) => { ...@@ -180,7 +180,7 @@ export const hexToRgb = (hex) => {
: null : null
} }
export const clacTopicText = (type, radio, checkbox, judge, fill, textarea) => { export const calcTopicText = (type, radio, checkbox, judge, fill, textarea) => {
let i = 0 let i = 0
const arr = ['一', '二', '三', '四', '五'] const arr = ['一', '二', '三', '四', '五']
if (type === 'radio') { if (type === 'radio') {
......
...@@ -15,12 +15,12 @@ export default defineConfig(() => { ...@@ -15,12 +15,12 @@ export default defineConfig(() => {
port: 5174, port: 5174,
strictPort: true, strictPort: true,
proxy: { proxy: {
'/api/admin': { // '/api/admin': {
target: 'http://127.0.0.1:7419', // target: 'http://127.0.0.1:7419',
changeOrigin: true, // changeOrigin: true,
secure: false, // secure: false,
rewrite: (path) => path.replace(/^\/api\/admin/, ''), // rewrite: (path) => path.replace(/^\/api\/admin/, ''),
}, // },
'/api': 'https://zijingebook.ezijing.com', '/api': 'https://zijingebook.ezijing.com',
}, },
}, },
......
...@@ -33,10 +33,10 @@ ...@@ -33,10 +33,10 @@
"@types/react-dom": "^19.2.3", "@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^6.0.5", "@vitejs/plugin-react": "^6.0.5",
"jsdom": "^29.1.1", "jsdom": "^29.1.1",
"oxfmt": "^0.59.0", "oxfmt": "^0.64.0",
"oxlint": "^1.74.0", "oxlint": "^1.79.0",
"typescript": "^7.0.2", "typescript": "^7.0.2",
"vite": "^8.2.1", "vite": "^8.2.2",
"vite-plugin-mkcert": "^2.1.0", "vite-plugin-mkcert": "^2.1.0",
"vitest": "^4.1.10" "vitest": "^4.1.10"
} }
......
.mobile-download-modal .ant-modal-content { .mobile-download-modal .mobile-download-modal__container {
padding: 40px 52px 48px; padding: 40px 52px 48px;
border-radius: 24px; border-radius: 24px;
font-family: font-family:
...@@ -6,14 +6,14 @@ ...@@ -6,14 +6,14 @@
'Helvetica Neue', Arial, sans-serif; 'Helvetica Neue', Arial, sans-serif;
} }
.mobile-download-modal .ant-modal-close { .mobile-download-modal .mobile-download-modal__close {
top: 22px; top: 22px;
right: 26px; right: 26px;
color: #b8bcc3; color: #b8bcc3;
font-size: 28px; font-size: 28px;
} }
.mobile-download-modal .ant-modal-close:hover { .mobile-download-modal .mobile-download-modal__close:hover {
color: #90959d; color: #90959d;
background: transparent; background: transparent;
} }
...@@ -125,7 +125,7 @@ ...@@ -125,7 +125,7 @@
.mobile-download-modal { .mobile-download-modal {
max-width: calc(100vw - 32px); max-width: calc(100vw - 32px);
} }
.mobile-download-modal .ant-modal-content { .mobile-download-modal .mobile-download-modal__container {
padding: 28px 24px 36px; padding: 28px 24px 36px;
} }
.mobile-download-modal__content h2.ant-typography { .mobile-download-modal__content h2.ant-typography {
......
...@@ -38,6 +38,10 @@ export function MobileDownloadModal() { ...@@ -38,6 +38,10 @@ export function MobileDownloadModal() {
<Modal <Modal
centered centered
className='mobile-download-modal' className='mobile-download-modal'
classNames={{
container: 'mobile-download-modal__container',
close: 'mobile-download-modal__close',
}}
closeIcon={<CloseCircleFilled />} closeIcon={<CloseCircleFilled />}
footer={null} footer={null}
open={open} open={open}
......
差异被折叠。
...@@ -5,3 +5,6 @@ packages: ...@@ -5,3 +5,6 @@ packages:
allowBuilds: allowBuilds:
es5-ext: false es5-ext: false
esbuild: true esbuild: true
minimumReleaseAgeExclude:
- vite@8.2.2
Markdown 格式
0% 或
您添加了 0 人 到此讨论。请谨慎行事。
请先完成此评论的编辑!
请 注册 或者 后发表评论