Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
C
center-book
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
EzijingWeb
center-book
Commits
be72dcaa
提交
be72dcaa
authored
7月 29, 2026
作者:
王鹏飞
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
chore: update
上级
2be389ac
隐藏空白字符变更
内嵌
并排
正在显示
20 个修改的文件
包含
321 行增加
和
292 行删除
+321
-292
AiImageDialog.jsx
...r/wangeditor-customer/features/ai-media/AiImageDialog.jsx
+5
-2
AiVideoDialog.jsx
...r/wangeditor-customer/features/ai-media/AiVideoDialog.jsx
+5
-2
DigitalHumanDialog.jsx
...geditor-customer/features/ai-media/DigitalHumanDialog.jsx
+5
-2
AudioDialog.jsx
...editor/wangeditor-customer/features/audio/AudioDialog.jsx
+5
-2
SectionDialog.jsx
...tor-customer/features/chapter-structure/SectionDialog.jsx
+5
-3
TitleDialog.jsx
...ditor-customer/features/chapter-structure/TitleDialog.jsx
+5
-3
ExpandReadDialog.jsx
...editor-customer/features/expand-read/ExpandReadDialog.jsx
+2
-1
GalleryDialog.jsx
...or/wangeditor-customer/features/gallery/GalleryDialog.jsx
+5
-2
ImageDialog.jsx
...editor/wangeditor-customer/features/image/ImageDialog.jsx
+5
-2
index.js
...c/components/editor/wangeditor-customer/features/index.js
+2
-0
LinkDialog.jsx
...s/editor/wangeditor-customer/features/link/LinkDialog.jsx
+0
-1
feature.js
...nents/editor/wangeditor-customer/features/link/feature.js
+4
-1
PracticeSettingsDialog.jsx
...tor-customer/features/practice/PracticeSettingsDialog.jsx
+96
-241
feature.js
...tor/wangeditor-customer/features/table-actions/feature.js
+10
-0
insert-after-menu.js
...itor-customer/features/table-actions/insert-after-menu.js
+96
-0
VideoDialog.jsx
...editor/wangeditor-customer/features/video/VideoDialog.jsx
+5
-2
index.less
...dmin/src/components/editor/wangeditor-customer/index.less
+2
-2
editor-operations.js
...ts/editor/wangeditor-customer/shared/editor-operations.js
+24
-0
editor-config.js
...ponents/editor/wangeditor-customer/shell/editor-config.js
+14
-0
vite.config.js
apps/admin/vite.config.js
+26
-26
没有找到文件。
apps/admin/src/components/editor/wangeditor-customer/features/ai-media/AiImageDialog.jsx
浏览文件 @
be72dcaa
...
@@ -15,7 +15,10 @@ import {
...
@@ -15,7 +15,10 @@ import {
Radio
,
Radio
,
}
from
'antd'
}
from
'antd'
import
{
SlateTransforms
}
from
'@wangeditor/editor'
import
{
SlateTransforms
}
from
'@wangeditor/editor'
import
{
removeSelectedEmptyParagraph
}
from
'../../shared/editor-operations'
import
{
insertBlockNodesAndFocus
,
removeSelectedEmptyParagraph
,
}
from
'../../shared/editor-operations'
const
{
TextArea
}
=
Input
const
{
TextArea
}
=
Input
import
'../ai-research/search.less'
import
'../ai-research/search.less'
import
'./image.less'
import
'./image.less'
...
@@ -147,7 +150,7 @@ export default function AIImageModal(props) {
...
@@ -147,7 +150,7 @@ export default function AIImageModal(props) {
children
:
[{
text
:
prompt
||
'AI生成的图片'
}],
children
:
[{
text
:
prompt
||
'AI生成的图片'
}],
}
}
SlateTransforms
.
insertNodes
(
editor
,
[
oImg
,
oP
])
insertBlockNodesAndFocus
(
editor
,
SlateTransforms
,
[
oImg
,
oP
])
message
.
success
(
'图片已插入编辑器!'
)
message
.
success
(
'图片已插入编辑器!'
)
setIsModalOpen
(
false
)
setIsModalOpen
(
false
)
}
else
{
}
else
{
...
...
apps/admin/src/components/editor/wangeditor-customer/features/ai-media/AiVideoDialog.jsx
浏览文件 @
be72dcaa
...
@@ -20,7 +20,10 @@ import {
...
@@ -20,7 +20,10 @@ import {
InputNumber
,
InputNumber
,
}
from
'antd'
}
from
'antd'
import
{
SlateTransforms
}
from
'@wangeditor/editor'
import
{
SlateTransforms
}
from
'@wangeditor/editor'
import
{
removeSelectedEmptyParagraph
}
from
'../../shared/editor-operations'
import
{
insertBlockNodesAndFocus
,
removeSelectedEmptyParagraph
,
}
from
'../../shared/editor-operations'
import
{
useVideo
}
from
'@ezijing/ai-react'
import
{
useVideo
}
from
'@ezijing/ai-react'
import
{
uploadFileByUrl
}
from
'@/utils/oss'
import
{
uploadFileByUrl
}
from
'@/utils/oss'
import
'../ai-research/search.less'
import
'../ai-research/search.less'
...
@@ -128,7 +131,7 @@ export default function AIVideoModal(props) {
...
@@ -128,7 +131,7 @@ export default function AIVideoModal(props) {
editor
.
restoreSelection
()
editor
.
restoreSelection
()
removeEmptyParagraph
(
editor
)
removeEmptyParagraph
(
editor
)
SlateTransforms
.
insertNodes
(
editor
,
{
insertBlockNodesAndFocus
(
editor
,
SlateTransforms
,
{
type
:
'chapterVideo'
,
type
:
'chapterVideo'
,
videoUrl
:
ossUrl
,
videoUrl
:
ossUrl
,
title
:
videoPrompt
||
'AI生成的视频'
,
title
:
videoPrompt
||
'AI生成的视频'
,
...
...
apps/admin/src/components/editor/wangeditor-customer/features/ai-media/DigitalHumanDialog.jsx
浏览文件 @
be72dcaa
...
@@ -26,7 +26,10 @@ import { saveAs } from 'file-saver'
...
@@ -26,7 +26,10 @@ import { saveAs } from 'file-saver'
import
{
uploadFileByUrl
}
from
'@/utils/oss'
import
{
uploadFileByUrl
}
from
'@/utils/oss'
import
useDigitalHuman
from
'@/components/editor/hooks/useDigitalHuman'
import
useDigitalHuman
from
'@/components/editor/hooks/useDigitalHuman'
import
'./digital-human.less'
import
'./digital-human.less'
import
{
removeSelectedEmptyParagraph
}
from
'../../shared/editor-operations'
import
{
insertBlockNodesAndFocus
,
removeSelectedEmptyParagraph
,
}
from
'../../shared/editor-operations'
const
{
TextArea
}
=
Input
const
{
TextArea
}
=
Input
...
@@ -100,7 +103,7 @@ export default function AIDigitalHumanModal(props) {
...
@@ -100,7 +103,7 @@ export default function AIDigitalHumanModal(props) {
if
(
editor
)
{
if
(
editor
)
{
editor
.
restoreSelection
()
editor
.
restoreSelection
()
removeSelectedEmptyParagraph
(
editor
,
SlateTransforms
)
removeSelectedEmptyParagraph
(
editor
,
SlateTransforms
)
SlateTransforms
.
insertNodes
(
editor
,
{
insertBlockNodesAndFocus
(
editor
,
SlateTransforms
,
{
type
:
'chapterVideo'
,
type
:
'chapterVideo'
,
videoUrl
:
ossUrl
,
videoUrl
:
ossUrl
,
title
:
`
${
generatedVideo
.
figureName
}
- AI播报`
,
title
:
`
${
generatedVideo
.
figureName
}
- AI播报`
,
...
...
apps/admin/src/components/editor/wangeditor-customer/features/audio/AudioDialog.jsx
浏览文件 @
be72dcaa
...
@@ -4,7 +4,10 @@ import { CloudUploadOutlined } from '@ant-design/icons'
...
@@ -4,7 +4,10 @@ import { CloudUploadOutlined } from '@ant-design/icons'
import
{
SlateTransforms
}
from
'@wangeditor/editor'
import
{
SlateTransforms
}
from
'@wangeditor/editor'
import
'../../index.less'
import
'../../index.less'
import
{
uploadFile
}
from
'@/utils/oss'
import
{
uploadFile
}
from
'@/utils/oss'
import
{
removeSelectedEmptyParagraph
}
from
'../../shared/editor-operations'
import
{
insertBlockNodesAndFocus
,
removeSelectedEmptyParagraph
,
}
from
'../../shared/editor-operations'
const
{
Dragger
}
=
Upload
const
{
Dragger
}
=
Upload
...
@@ -70,7 +73,7 @@ const AudioModal = ({ open, onClose, payload = {}, runtime }) => {
...
@@ -70,7 +73,7 @@ const AudioModal = ({ open, onClose, payload = {}, runtime }) => {
removeSelectedEmptyParagraph
(
editor
,
SlateTransforms
)
removeSelectedEmptyParagraph
(
editor
,
SlateTransforms
)
SlateTransforms
.
insertNodes
(
editor
,
{
insertBlockNodesAndFocus
(
editor
,
SlateTransforms
,
{
type
:
'chapterAudio'
,
type
:
'chapterAudio'
,
audioUrl
:
values
.
audioUrl
,
audioUrl
:
values
.
audioUrl
,
title
:
values
.
audioTitle
,
title
:
values
.
audioTitle
,
...
...
apps/admin/src/components/editor/wangeditor-customer/features/chapter-structure/SectionDialog.jsx
浏览文件 @
be72dcaa
...
@@ -12,7 +12,10 @@ import {
...
@@ -12,7 +12,10 @@ import {
Col
,
Col
,
}
from
'antd'
}
from
'antd'
import
{
SlateEditor
,
SlateTransforms
,
SlateElement
}
from
'@wangeditor/editor'
import
{
SlateEditor
,
SlateTransforms
,
SlateElement
}
from
'@wangeditor/editor'
import
{
removeSelectedEmptyParagraph
}
from
'../../shared/editor-operations'
import
{
insertBlockNodesAndFocus
,
removeSelectedEmptyParagraph
,
}
from
'../../shared/editor-operations'
import
{
fontFamilyList
,
fontSizeList
}
from
'../../shared/editor-settings'
import
{
fontFamilyList
,
fontSizeList
}
from
'../../shared/editor-settings'
import
'../../index.less'
import
'../../index.less'
...
@@ -104,7 +107,7 @@ const ChapterItemModal = (props, ref) => {
...
@@ -104,7 +107,7 @@ const ChapterItemModal = (props, ref) => {
}
}
const
random
=
Math
.
random
().
toString
(
10
).
substring
(
2
,
10
)
const
random
=
Math
.
random
().
toString
(
10
).
substring
(
2
,
10
)
editor
.
insertNode
(
{
insertBlockNodesAndFocus
(
editor
,
SlateTransforms
,
{
type
:
'chapterSection'
,
type
:
'chapterSection'
,
title
:
values
.
title
,
title
:
values
.
title
,
textColor
:
values
.
textColor
,
textColor
:
values
.
textColor
,
...
@@ -235,7 +238,6 @@ const ChapterItemModal = (props, ref) => {
...
@@ -235,7 +238,6 @@ const ChapterItemModal = (props, ref) => {
controls=
{
false
}
controls=
{
false
}
placeholder=
''
placeholder=
''
style=
{
{
width
:
'100%'
,
textAlign
:
'left'
}
}
style=
{
{
width
:
'100%'
,
textAlign
:
'left'
}
}
allowClear
/>
/>
</
Form
.
Item
>
</
Form
.
Item
>
</
Col
>
</
Col
>
...
...
apps/admin/src/components/editor/wangeditor-customer/features/chapter-structure/TitleDialog.jsx
浏览文件 @
be72dcaa
...
@@ -16,7 +16,10 @@ import {
...
@@ -16,7 +16,10 @@ import {
}
from
'antd'
}
from
'antd'
import
{
CloudUploadOutlined
}
from
'@ant-design/icons'
import
{
CloudUploadOutlined
}
from
'@ant-design/icons'
import
{
SlateEditor
,
SlateTransforms
,
SlateElement
}
from
'@wangeditor/editor'
import
{
SlateEditor
,
SlateTransforms
,
SlateElement
}
from
'@wangeditor/editor'
import
{
removeSelectedEmptyParagraph
}
from
'../../shared/editor-operations'
import
{
insertBlockNodesAndFocus
,
removeSelectedEmptyParagraph
,
}
from
'../../shared/editor-operations'
import
{
fontFamilyList
,
fontSizeList
}
from
'../../shared/editor-settings'
import
{
fontFamilyList
,
fontSizeList
}
from
'../../shared/editor-settings'
import
'../../index.less'
import
'../../index.less'
...
@@ -161,7 +164,7 @@ const ImageModal = (props, ref) => {
...
@@ -161,7 +164,7 @@ const ImageModal = (props, ref) => {
const
docBody
=
parser
.
parseFromString
(
html
,
'text/html'
)
const
docBody
=
parser
.
parseFromString
(
html
,
'text/html'
)
const
section
=
docBody
.
body
.
querySelectorAll
(
'.chapter-item-header'
)
// 是否存在章头
const
section
=
docBody
.
body
.
querySelectorAll
(
'.chapter-item-header'
)
// 是否存在章头
editor
.
insertNode
(
{
insertBlockNodesAndFocus
(
editor
,
SlateTransforms
,
{
type
:
'chapterHeader'
,
type
:
'chapterHeader'
,
title
:
values
.
title
,
title
:
values
.
title
,
textColor
:
values
.
textColor
,
textColor
:
values
.
textColor
,
...
@@ -347,7 +350,6 @@ const ImageModal = (props, ref) => {
...
@@ -347,7 +350,6 @@ const ImageModal = (props, ref) => {
controls=
{
false
}
controls=
{
false
}
placeholder=
''
placeholder=
''
style=
{
{
width
:
'100%'
,
textAlign
:
'left'
}
}
style=
{
{
width
:
'100%'
,
textAlign
:
'left'
}
}
allowClear
/>
/>
</
Form
.
Item
>
</
Form
.
Item
>
</
Col
>
</
Col
>
...
...
apps/admin/src/components/editor/wangeditor-customer/features/expand-read/ExpandReadDialog.jsx
浏览文件 @
be72dcaa
...
@@ -21,6 +21,7 @@ import '../../index.less'
...
@@ -21,6 +21,7 @@ import '../../index.less'
import
{
addExpandRead
,
expandReadInfo
}
from
'../../shared/request'
import
{
addExpandRead
,
expandReadInfo
}
from
'../../shared/request'
import
{
import
{
findElementPathByAttribute
,
findElementPathByAttribute
,
insertBlockNodesAndFocus
,
removeSelectedEmptyParagraph
,
removeSelectedEmptyParagraph
,
}
from
'../../shared/editor-operations'
}
from
'../../shared/editor-operations'
...
@@ -148,7 +149,7 @@ const ExpandModal = (props, ref) => {
...
@@ -148,7 +149,7 @@ const ExpandModal = (props, ref) => {
})
})
if
(
parseInt
(
values
.
flex
)
===
1
)
{
if
(
parseInt
(
values
.
flex
)
===
1
)
{
editor
.
insertNode
(
{
insertBlockNodesAndFocus
(
editor
,
SlateTransforms
,
{
type
:
'chapterExpandRead'
,
type
:
'chapterExpandRead'
,
flex
:
parseInt
(
values
.
flex
),
flex
:
parseInt
(
values
.
flex
),
name
:
values
.
name
,
name
:
values
.
name
,
...
...
apps/admin/src/components/editor/wangeditor-customer/features/gallery/GalleryDialog.jsx
浏览文件 @
be72dcaa
...
@@ -5,7 +5,10 @@ import { addGallery } from '../../shared/request'
...
@@ -5,7 +5,10 @@ import { addGallery } from '../../shared/request'
import
{
SlateTransforms
}
from
'@wangeditor/editor'
import
{
SlateTransforms
}
from
'@wangeditor/editor'
import
{
findNodeWithParent
,
fontSizeList
}
from
'../../shared/editor-settings'
import
{
findNodeWithParent
,
fontSizeList
}
from
'../../shared/editor-settings'
import
{
removeSelectedEmptyParagraph
}
from
'../../shared/editor-operations'
import
{
insertBlockNodesAndFocus
,
removeSelectedEmptyParagraph
,
}
from
'../../shared/editor-operations'
import
GalleryFormItem
from
'./GalleryItem'
import
GalleryFormItem
from
'./GalleryItem'
const
randomOne
=
Math
.
random
().
toString
(
16
).
substring
(
2
,
10
)
const
randomOne
=
Math
.
random
().
toString
(
16
).
substring
(
2
,
10
)
...
@@ -274,7 +277,7 @@ const GalleryModal = (props, ref) => {
...
@@ -274,7 +277,7 @@ const GalleryModal = (props, ref) => {
children
:
[{
text
:
''
}],
children
:
[{
text
:
''
}],
})
})
}
else
{
}
else
{
editor
.
insertNode
(
{
insertBlockNodesAndFocus
(
editor
,
SlateTransforms
,
{
type
:
'chapterGallery'
,
type
:
'chapterGallery'
,
title
:
galleryTitle
,
title
:
galleryTitle
,
galleryList
:
encodeURI
(
JSON
.
stringify
(
gallery
)),
galleryList
:
encodeURI
(
JSON
.
stringify
(
gallery
)),
...
...
apps/admin/src/components/editor/wangeditor-customer/features/image/ImageDialog.jsx
浏览文件 @
be72dcaa
...
@@ -4,7 +4,10 @@ import { CloudUploadOutlined } from '@ant-design/icons'
...
@@ -4,7 +4,10 @@ import { CloudUploadOutlined } from '@ant-design/icons'
import
{
DomEditor
,
SlateTransforms
}
from
'@wangeditor/editor'
import
{
DomEditor
,
SlateTransforms
}
from
'@wangeditor/editor'
import
'../../index.less'
import
'../../index.less'
import
OnlineImageList
from
'../../shared/online-image/OnlineImageList'
import
OnlineImageList
from
'../../shared/online-image/OnlineImageList'
import
{
removeSelectedEmptyParagraph
}
from
'../../shared/editor-operations'
import
{
insertBlockNodesAndFocus
,
removeSelectedEmptyParagraph
,
}
from
'../../shared/editor-operations'
import
{
uploadFile
}
from
'@/utils/oss'
import
{
uploadFile
}
from
'@/utils/oss'
...
@@ -122,7 +125,7 @@ const ImageModal = (props, ref) => {
...
@@ -122,7 +125,7 @@ const ImageModal = (props, ref) => {
nodes
.
push
(
oP
)
nodes
.
push
(
oP
)
}
}
SlateTransforms
.
insertNodes
(
editor
,
nodes
)
insertBlockNodesAndFocus
(
editor
,
SlateTransforms
,
nodes
)
clear
()
clear
()
}
}
...
...
apps/admin/src/components/editor/wangeditor-customer/features/index.js
浏览文件 @
be72dcaa
...
@@ -15,6 +15,7 @@ import image from './image/feature'
...
@@ -15,6 +15,7 @@ import image from './image/feature'
import
link
from
'./link/feature'
import
link
from
'./link/feature'
import
practice
from
'./practice/feature'
import
practice
from
'./practice/feature'
import
preview
from
'./preview/feature'
import
preview
from
'./preview/feature'
import
tableActions
from
'./table-actions/feature'
import
tooltip
from
'./tooltip/feature'
import
tooltip
from
'./tooltip/feature'
import
video
from
'./video/feature'
import
video
from
'./video/feature'
...
@@ -37,6 +38,7 @@ export const editorFeatures = [
...
@@ -37,6 +38,7 @@ export const editorFeatures = [
aiResearch
,
aiResearch
,
preview
,
preview
,
history
,
history
,
tableActions
,
]
]
export
const
editorFeatureRegistry
=
createFeatureRegistry
(
editorFeatures
)
export
const
editorFeatureRegistry
=
createFeatureRegistry
(
editorFeatures
)
apps/admin/src/components/editor/wangeditor-customer/features/link/LinkDialog.jsx
浏览文件 @
be72dcaa
...
@@ -257,7 +257,6 @@ const LinkModal = (props, ref) => {
...
@@ -257,7 +257,6 @@ const LinkModal = (props, ref) => {
</
Form
.
Item
>
</
Form
.
Item
>
<
Form
.
Item
label=
{
` `
}
>
<
Form
.
Item
label=
{
` `
}
>
<
ColorPicker
<
ColorPicker
disabledAlpha
value=
{
themeValue
}
value=
{
themeValue
}
defaultValue=
{
themeValue
}
defaultValue=
{
themeValue
}
format=
'hex'
format=
'hex'
...
...
apps/admin/src/components/editor/wangeditor-customer/features/link/feature.js
浏览文件 @
be72dcaa
...
@@ -17,7 +17,10 @@ export default defineEditorFeature({
...
@@ -17,7 +17,10 @@ export default defineEditorFeature({
{
{
name
:
'CustomerLinkClick'
,
name
:
'CustomerLinkClick'
,
handler
:
({
editor
})
=>
handler
:
({
editor
})
=>
openEditorDialog
(
editor
,
'link.insert'
,
{
selectionSize
:
getSelectionFontSize
(
editor
)
}),
openEditorDialog
(
editor
,
'link.insert'
,
{
selectionSize
:
getSelectionFontSize
(
editor
),
theme
:
'#ab1941'
,
}),
},
},
],
],
})
})
apps/admin/src/components/editor/wangeditor-customer/features/practice/PracticeSettingsDialog.jsx
浏览文件 @
be72dcaa
import
React
,
{
useState
,
useEffect
,
forwardRef
,
useImperativeHandle
,
useRef
}
from
'react'
import
{
useState
,
forwardRef
,
useImperativeHandle
}
from
'react'
import
{
import
{
Divider
,
Input
,
Space
,
Button
,
Form
,
ColorPicker
}
from
'antd'
Modal
,
Row
,
Col
,
Divider
,
Upload
,
Input
,
Space
,
Button
,
Form
,
Spin
,
message
,
ColorPicker
,
}
from
'antd'
import
{
CloseOutlined
}
from
'@ant-design/icons'
import
{
useEditorStore
}
from
'@/stores/editorStore'
import
{
DomEditor
,
SlateEditor
,
SlateTransforms
,
SlateElement
}
from
'@wangeditor/editor'
import
ListTopic
from
'./components/list'
import
{
SlateTransforms
,
SlateEditor
,
SlateElement
}
from
'@wangeditor/editor'
import
CustomerTopic
from
'./components/customer'
import
{
import
InsertTopic
from
'./components/insert'
insertBlockNodesAndFocus
,
import
iconPractice
from
'@/assets/images/icon_practice.png'
removeSelectedEmptyParagraph
,
import
iconClose
from
'@/assets/images/icon_chapter_close.png'
}
from
'../../shared/editor-operations'
import
{
getChapterTopic
}
from
'../../shared/request'
import
{
bookNameList
}
from
'./question-api'
import
'./styles.less'
import
{
useEditorStore
}
from
'@/stores/editorStore'
import
'../../index.less'
const
PracticeSettingModal
=
(
props
,
ref
)
=>
{
const
PracticeModal
=
(
props
,
ref
)
=>
{
const
{
editor
,
chapterId
,
bookId
,
closePanel
}
=
props
const
{
bookId
,
chapterId
,
setPracticeOpenVisible
}
=
props
const
practiceRandom
=
useEditorStore
((
state
)
=>
state
.
practiceRandom
)
const
practiceTitle
=
useEditorStore
((
state
)
=>
state
.
practiceTitle
)
const
practiceTheme
=
useEditorStore
((
state
)
=>
state
.
practiceTheme
)
const
setPracticeRandom
=
useEditorStore
((
state
)
=>
state
.
setPracticeRandom
)
const
setPracticeRandom
=
useEditorStore
((
state
)
=>
state
.
setPracticeRandom
)
const
[
themeValue
,
setThemeValue
]
=
useState
(
practiceTheme
)
const
{
editor
}
=
props
const
[
form
]
=
Form
.
useForm
()
const
listRef
=
useRef
()
const
[
themeValue
,
setThemeValue
]
=
useState
(
'#ab1941'
)
const
customerTopicRef
=
useRef
()
const
[
initValues
,
setInitValues
]
=
useState
({
practice
:
''
,
theme
:
'#ab1941'
})
const
[
nodes
,
setNodes
]
=
useState
(
null
)
const
[
customerType
,
setCustomerType
]
=
useState
(
''
)
const
[
practiceTitleVisible
,
setPracticeTitleVisible
]
=
useState
(
false
)
// 是否显示可编辑
useImperativeHandle
(
ref
,
()
=>
{
const
[
practiceTitleValue
,
setPracticeTitleValue
]
=
useState
(
practiceTitle
)
// input 标题
return
{
const
[
practiceStatus
,
setPracticeStatus
]
=
useState
(
false
)
// 手动还是自动
nodes
,
}
// 右边勾选的列表
})
const
[
chooseList
,
setChooseList
]
=
useState
([])
// 线上的题库
const
[
onlineList
,
setOnloneList
]
=
useState
([])
// 左边插入的列表
const
[
insertList
,
setInsertList
]
=
useState
([])
const
[
bookNameIdData
,
setbookNameIdData
]
=
useState
([])
const
getbookNameList
=
async
()
=>
{
const
res
=
await
bookNameList
({})
setbookNameIdData
(
res
)
}
useEffect
(()
=>
{
getbookNameList
()
},
[])
const
textColorChange
=
(
value
)
=>
{
const
textColorChange
=
(
value
)
=>
{
const
hex
=
typeof
value
===
'string'
?
value
:
value
?.
toHexString
()
const
hex
=
typeof
value
===
'string'
?
value
:
value
?.
toHexString
()
setThemeValue
(
hex
)
setThemeValue
(
hex
)
form
.
setFieldsValue
({
theme
:
hex
})
}
}
// 获取
const
getTopicList
=
async
()
=>
{
const
data
=
await
getChapterTopic
({
position
:
practiceRandom
,
book_id
:
bookId
,
chapter_id
:
chapterId
,
})
if
(
data
&&
data
.
length
>
0
)
{
const
dataSource
=
[]
data
.
forEach
((
item
,
index
)
=>
{
dataSource
.
push
({
...
item
,
choose_id
:
item
.
question_id
})
})
setOnloneList
(
dataSource
)
if
(
insertList
.
length
===
0
)
{
setInsertList
(
dataSource
)
}
else
{
const
tempChoose
=
[...
insertList
]
const
ids
=
tempChoose
.
map
((
item
)
=>
parseInt
(
item
.
choose_id
))
dataSource
.
forEach
((
item
)
=>
{
if
(
!
ids
.
includes
(
parseInt
(
item
.
choose_id
)))
{
tempChoose
.
push
(
item
)
}
})
setInsertList
(
tempChoose
)
}
if
(
chooseList
.
length
===
0
)
{
setChooseList
(
dataSource
)
}
else
{
const
tempChoose
=
[...
chooseList
]
const
ids
=
tempChoose
.
map
((
item
)
=>
parseInt
(
item
.
choose_id
))
dataSource
.
forEach
((
item
)
=>
{
if
(
!
ids
.
includes
(
parseInt
(
item
.
choose_id
)))
{
tempChoose
.
push
(
item
)
}
})
setChooseList
(
tempChoose
)
}
}
}
useEffect
(()
=>
{
if
(
bookId
&&
chapterId
&&
practiceRandom
)
{
getTopicList
()
}
},
[
bookId
,
chapterId
,
practiceRandom
])
// 设置标题
const
changePracticeTitle
=
()
=>
{
setPracticeTitleValue
(
practiceTitle
)
setPracticeTitleVisible
(
true
)
}
const
submitPracticeTitle
=
()
=>
{
editor
.
restoreSelection
()
const
callback
=
(
practiceNum
,
practiceTitle
)
=>
{
const
nodeEntries
=
SlateEditor
.
nodes
(
editor
,
{
const
nodeEntries
=
SlateEditor
.
nodes
(
editor
,
{
match
:
(
node
)
=>
{
match
:
(
node
)
=>
{
// JS syntax
// JS syntax
if
(
SlateElement
.
isElement
(
node
))
{
if
(
SlateElement
.
isElement
(
node
))
{
if
(
node
.
type
===
'chapterPractice'
)
{
if
(
node
.
type
===
'chapterPractice'
)
{
return
true
// 匹配 chapterHeader
return
true
}
}
}
}
return
false
return
false
...
@@ -130,148 +45,88 @@ const PracticeSettingModal = (props, ref) => {
...
@@ -130,148 +45,88 @@ const PracticeSettingModal = (props, ref) => {
universal
:
true
,
universal
:
true
,
})
})
if
(
nodeEntries
)
{
setNodes
(
nodeEntries
)
for
(
const
nodeEntry
of
nodeEntries
)
{
setPracticeRandom
({
practiceNum
,
practiceTitle
})
const
[
node
,
path
]
=
nodeEntry
// console.log('选中了 chapterHeader 节点', node);
// console.log('节点 path 是', path);
if
(
node
.
practiceNum
===
practiceRandom
)
{
SlateTransforms
.
setNodes
(
editor
,
{
...
node
,
title
:
practiceTitleValue
,
theme
:
themeValue
},
{
at
:
path
},
)
setPracticeRandom
({
practiceNum
:
node
.
practiceNum
,
practiceTitle
:
practiceTitleValue
})
setPracticeTitleVisible
(
false
)
return
false
}
}
}
return
}
}
// 添加题目到左边
const
onFinish
=
(
values
)
=>
{
const
addTopicList
=
()
=>
{
editor
.
restoreSelection
()
if
(
chooseList
.
length
===
0
)
{
message
.
error
(
'您还没有勾选题目!'
)
return
}
const
tempChoose
=
[...
insertList
]
removeSelectedEmptyParagraph
(
editor
,
SlateTransforms
)
const
ids
=
tempChoose
.
map
((
item
)
=>
parseInt
(
item
.
choose_id
))
chooseList
.
forEach
((
item
)
=>
{
const
practiceNum
=
Math
.
random
().
toString
(
32
).
substring
(
2
,
10
)
if
(
!
ids
.
includes
(
parseInt
(
item
.
choose_id
)))
{
insertBlockNodesAndFocus
(
editor
,
SlateTransforms
,
{
tempChoose
.
push
(
item
)
type
:
'chapterPractice'
,
}
title
:
values
.
practice
,
practiceNum
:
practiceNum
,
bookId
,
chapterId
,
theme
:
values
.
theme
,
callback
:
callback
,
children
:
[{
text
:
''
}],
})
})
setInsertList
(
tempChoose
)
form
.
resetFields
()
}
setPracticeOpenVisible
(
false
)
editor
.
focus
()
const
getTopList
=
()
=>
{
listRef
.
current
.
setPage
(
1
)
listRef
.
current
.
getTopicTypeList
()
}
}
return
(
return
(
<
div
>
<
div
>
<
Row
gutter=
'20'
className=
'practice-topic-row'
>
<
Divider
/>
<
Col
span=
{
12
}
className=
'common practice-left'
>
<
div
className=
'editor-content-form'
>
<
div
className=
'practice-header'
>
<
Form
<
div
className=
'practice-l-img'
>
layout=
'vertical'
{
/* <img src={iconPractice} alt='' /> */
}
name=
'validate_other'
<
svg
className=
'svg-icon'
aria
-
hidden=
'true'
>
form=
{
form
}
<
use
xlinkHref=
'#icon-writing'
></
use
>
onFinish=
{
onFinish
}
</
svg
>
initialValues=
{
initValues
}
>
<
Form
.
Item
label=
'标题'
name=
'practice'
rules=
{
[{
required
:
true
,
message
:
'请输入标题'
}]
}
extra=
'最多输入100字'
>
<
Input
maxLength=
{
100
}
placeholder=
''
allowClear
/>
</
Form
.
Item
>
<
Form
.
Item
>
<
div
className=
'justcontent-color-inline'
>
<
Form
.
Item
label=
'练习主题色'
name=
'theme'
className=
'flex-max'
rules=
{
[
{
required
:
true
,
message
:
'请选择颜色'
},
{
pattern
:
/^#
[
0-9A-Fa-f
]
{6}$/i
,
message
:
'请输入正确的16进制色值'
},
]
}
>
<
Input
placeholder=
''
allowClear
/>
</
Form
.
Item
>
<
Form
.
Item
label=
{
` `
}
>
<
ColorPicker
disabledAlpha
value=
{
themeValue
}
defaultValue=
{
themeValue
}
format=
'hex'
onChange=
{
textColorChange
}
/>
</
Form
.
Item
>
</
div
>
</
div
>
<
div
className=
'practice-l-title'
>
</
Form
.
Item
>
{
!
practiceTitleVisible
&&
(
<
Form
.
Item
className=
'editor-form-buttons'
>
<
h2
onClick=
{
changePracticeTitle
}
className=
'title'
>
<
Space
>
<
ColorPicker
value=
{
themeValue
}
defaultValue=
{
themeValue
}
size=
'small'
disabled
/>
<
Button
type=
'default'
onClick=
{
()
=>
setPracticeOpenVisible
(
false
)
}
>
<
span
className=
'titles'
>
{
practiceTitle
}
</
span
>
取消
<
span
className=
'click'
>
(可点击编辑)
</
span
>
</
h2
>
)
}
{
practiceTitleVisible
&&
(
<
div
style=
{
{
marginTop
:
2
}
}
>
<
Space
>
<
Input
value=
{
practiceTitleValue
}
onChange=
{
(
e
)
=>
setPracticeTitleValue
(
e
.
target
.
value
)
}
/>
<
div
style=
{
{
marginTop
:
2
}
}
>
<
ColorPicker
disabledAlpha
value=
{
themeValue
}
defaultValue=
{
themeValue
}
format=
'hex'
onChange=
{
textColorChange
}
showText
/>
</
div
>
<
Button
type=
'primary'
onClick=
{
submitPracticeTitle
}
>
确定
</
Button
>
<
Button
type=
'default'
onClick=
{
()
=>
setPracticeTitleVisible
(
false
)
}
>
取消
</
Button
>
</
Space
>
</
div
>
)
}
</
div
>
</
div
>
<
div
className=
'practice-topic-list'
>
<
InsertTopic
insertList=
{
insertList
}
setInsertList=
{
setInsertList
}
chooseList=
{
chooseList
}
setChooseList=
{
setChooseList
}
practiceRandom=
{
practiceRandom
}
chapterId=
{
chapterId
}
bookId=
{
bookId
}
closePanel=
{
closePanel
}
/>
</
div
>
</
Col
>
<
Col
span=
{
12
}
className=
'common practice-right'
>
<
div
className=
'practice-header right'
>
<
div
style=
{
{
marginTop
:
5
}
}
>
<
Button
type=
'default'
onClick=
{
()
=>
setPracticeStatus
(
!
practiceStatus
)
}
>
{
practiceStatus
?
'自动添加'
:
'手动添加'
}
</
Button
>
</
Button
>
</
div
>
<
Button
type=
'primary'
htmlType=
'submit'
>
<
Button
插入
type=
'link'
</
Button
>
icon=
{
<
CloseOutlined
style=
{
{
color
:
'#b83956'
}
}
/>
}
</
Space
>
onClick=
{
closePanel
}
</
Form
.
Item
>
></
Button
>
</
Form
>
</
div
>
</
div
>
<
div
className=
'practice-topic-list'
>
{
practiceStatus
?
(
<
CustomerTopic
ref=
{
customerTopicRef
}
setPracticeStatus=
{
setPracticeStatus
}
getTopList=
{
getTopList
}
bookNameIdData=
{
bookNameIdData
}
bookId=
{
bookId
}
setCustomerType=
{
setCustomerType
}
/>
)
:
(
<
ListTopic
ref=
{
listRef
}
chooseList=
{
chooseList
}
setChooseList=
{
setChooseList
}
addTopicList=
{
addTopicList
}
practiceStatus=
{
practiceStatus
}
bookNameIdData=
{
bookNameIdData
}
bookId=
{
bookId
}
customerType=
{
customerType
}
/>
)
}
</
div
>
</
Col
>
</
Row
>
</
div
>
</
div
>
)
)
}
}
export
default
forwardRef
(
Practice
Setting
Modal
)
export
default
forwardRef
(
PracticeModal
)
apps/admin/src/components/editor/wangeditor-customer/features/table-actions/feature.js
0 → 100644
浏览文件 @
be72dcaa
import
{
defineEditorFeature
}
from
'../../core/define-editor-feature'
import
{
insertTableColAfterMenu
,
insertTableRowAfterMenu
}
from
'./insert-after-menu'
export
default
defineEditorFeature
({
id
:
'table-actions'
,
menus
:
[
{
order
:
170
,
config
:
insertTableRowAfterMenu
},
{
order
:
180
,
config
:
insertTableColAfterMenu
},
],
})
apps/admin/src/components/editor/wangeditor-customer/features/table-actions/insert-after-menu.js
0 → 100644
浏览文件 @
be72dcaa
import
{
DomEditor
,
SlateRange
,
SlateTransforms
}
from
'@wangeditor/editor'
const
createCell
=
(
isHeader
=
false
)
=>
({
type
:
'table-cell'
,
...(
isHeader
?
{
isHeader
:
true
}
:
{}),
children
:
[{
text
:
''
}],
})
class
InsertTableAfterMenu
{
constructor
()
{
this
.
tag
=
'button'
}
getValue
()
{
return
''
}
isActive
()
{
return
false
}
isDisabled
(
editor
)
{
return
(
editor
.
selection
===
null
||
SlateRange
.
isExpanded
(
editor
.
selection
)
||
DomEditor
.
getSelectedNodeByType
(
editor
,
'table'
)
===
null
)
}
}
class
InsertTableRowAfter
extends
InsertTableAfterMenu
{
constructor
()
{
super
()
this
.
title
=
'向前插入行'
this
.
iconSvg
=
'<svg viewBox="0 0 1048 1024"><g transform="translate(0 917.504) scale(1 -1)"><path d="M707.7888 521.0112h-147.456v-147.456H488.2432v147.456h-147.456v68.8128h147.456v147.456h72.0896v-147.456h147.456zM0 917.504V0h1048.576v917.504H0zM327.68 65.536H65.536v196.608H327.68V65.536z m327.68 0H393.216v196.608h262.144V65.536z m327.68 0h-262.144v196.608h262.144V65.536z m0 258.8672H65.536v462.0288H983.04V324.4032z"></path></g></svg>'
}
exec
(
editor
)
{
if
(
this
.
isDisabled
(
editor
))
return
const
row
=
DomEditor
.
getSelectedNodeByType
(
editor
,
'table-row'
)
if
(
!
row
?.
children
?.
length
)
return
const
rowPath
=
DomEditor
.
findPath
(
editor
,
row
)
SlateTransforms
.
insertNodes
(
editor
,
{
type
:
'table-row'
,
children
:
row
.
children
.
map
(()
=>
createCell
()),
},
{
at
:
rowPath
},
)
}
}
class
InsertTableColAfter
extends
InsertTableAfterMenu
{
constructor
()
{
super
()
this
.
title
=
'向后插入列'
this
.
iconSvg
=
'<svg viewBox="0 0 1048 1024"><g transform="translate(1048 0) scale(-1 1)"><path d="M327.68 193.3312v186.7776H140.9024v91.7504H327.68v186.7776h88.4736V471.8592h190.0544V380.1088H416.1536V193.3312zM0 917.504V0h1048.576v917.504H0zM655.36 65.536H65.536v720.896H655.36V65.536z m327.68 0h-262.144v196.608h262.144V65.536z m0 262.144h-262.144v196.608h262.144V327.68z m0 262.144h-262.144v196.608h262.144v-196.608z"></path></g></svg>'
}
exec
(
editor
)
{
if
(
this
.
isDisabled
(
editor
))
return
const
table
=
DomEditor
.
getSelectedNodeByType
(
editor
,
'table'
)
const
cell
=
DomEditor
.
getSelectedNodeByType
(
editor
,
'table-cell'
)
if
(
!
table
||
!
cell
)
return
const
cellPath
=
DomEditor
.
findPath
(
editor
,
cell
)
const
columnIndex
=
cellPath
[
2
]
const
firstRowIsHeader
=
table
.
children
?.[
0
]?.
children
?.
every
((
item
)
=>
item
.
isHeader
)
table
.
children
.
forEach
((
_
,
rowIndex
)
=>
{
SlateTransforms
.
insertNodes
(
editor
,
createCell
(
rowIndex
===
0
&&
firstRowIsHeader
),
{
at
:
[
cellPath
[
0
],
rowIndex
,
columnIndex
+
1
],
})
})
}
}
export
const
insertTableRowAfterMenu
=
{
key
:
'insertTableRowAfter'
,
factory
()
{
return
new
InsertTableRowAfter
()
},
}
export
const
insertTableColAfterMenu
=
{
key
:
'insertTableColAfter'
,
factory
()
{
return
new
InsertTableColAfter
()
},
}
apps/admin/src/components/editor/wangeditor-customer/features/video/VideoDialog.jsx
浏览文件 @
be72dcaa
...
@@ -5,7 +5,10 @@ import { SlateTransforms } from '@wangeditor/editor'
...
@@ -5,7 +5,10 @@ import { SlateTransforms } from '@wangeditor/editor'
import
'../../index.less'
import
'../../index.less'
import
{
uploadFile
}
from
'@/utils/oss'
import
{
uploadFile
}
from
'@/utils/oss'
import
{
removeSelectedEmptyParagraph
}
from
'../../shared/editor-operations'
import
{
insertBlockNodesAndFocus
,
removeSelectedEmptyParagraph
,
}
from
'../../shared/editor-operations'
const
{
Dragger
}
=
Upload
const
{
Dragger
}
=
Upload
...
@@ -70,7 +73,7 @@ const VideoModal = ({ open, onClose, payload = {}, runtime }) => {
...
@@ -70,7 +73,7 @@ const VideoModal = ({ open, onClose, payload = {}, runtime }) => {
removeSelectedEmptyParagraph
(
editor
,
SlateTransforms
)
removeSelectedEmptyParagraph
(
editor
,
SlateTransforms
)
SlateTransforms
.
insertNodes
(
editor
,
{
insertBlockNodesAndFocus
(
editor
,
SlateTransforms
,
{
type
:
'chapterVideo'
,
type
:
'chapterVideo'
,
videoUrl
:
values
.
videoUrl
,
videoUrl
:
values
.
videoUrl
,
title
:
values
.
videoTitle
,
title
:
values
.
videoTitle
,
...
...
apps/admin/src/components/editor/wangeditor-customer/index.less
浏览文件 @
be72dcaa
...
@@ -532,13 +532,13 @@
...
@@ -532,13 +532,13 @@
align-items: center;
align-items: center;
justify-content: center;
justify-content: center;
width: 100%;
width: 100%;
max-height:
32
0px;
max-height:
11
0px;
overflow: hidden;
overflow: hidden;
img {
img {
display: block;
display: block;
max-width: 100%;
max-width: 100%;
max-height:
32
0px;
max-height:
11
0px;
width: auto;
width: auto;
height: auto;
height: auto;
object-fit: contain;
object-fit: contain;
...
...
apps/admin/src/components/editor/wangeditor-customer/shared/editor-operations.js
浏览文件 @
be72dcaa
...
@@ -13,6 +13,30 @@ export const removeSelectedEmptyParagraph = (editor, transforms) => {
...
@@ -13,6 +13,30 @@ export const removeSelectedEmptyParagraph = (editor, transforms) => {
if
(
path
)
transforms
.
removeNodes
(
editor
,
{
at
:
path
})
if
(
path
)
transforms
.
removeNodes
(
editor
,
{
at
:
path
})
}
}
export
const
insertBlockNodesAndFocus
=
(
editor
,
transforms
,
nodes
)
=>
{
const
insertedNodes
=
Array
.
isArray
(
nodes
)
?
nodes
:
[
nodes
]
const
lastInsertedNode
=
insertedNodes
[
insertedNodes
.
length
-
1
]
transforms
.
insertNodes
(
editor
,
insertedNodes
)
const
insertedIndex
=
editor
.
children
.
findIndex
((
node
)
=>
node
===
lastInsertedNode
)
if
(
insertedIndex
<
0
)
return
const
nextPath
=
[
insertedIndex
+
1
]
const
nextNode
=
editor
.
children
[
nextPath
[
0
]]
const
nextFirstChild
=
nextNode
?.
children
?.[
0
]
if
(
!
nextFirstChild
||
!
(
'text'
in
nextFirstChild
))
{
transforms
.
insertNodes
(
editor
,
{
type
:
'paragraph'
,
children
:
[{
text
:
''
}]
},
{
at
:
nextPath
},
)
}
transforms
.
select
(
editor
,
{
anchor
:
{
path
:
[...
nextPath
,
0
],
offset
:
0
},
focus
:
{
path
:
[...
nextPath
,
0
],
offset
:
0
},
})
}
export
const
findElementPathByAttribute
=
(
children
,
attribute
,
value
)
=>
{
export
const
findElementPathByAttribute
=
(
children
,
attribute
,
value
)
=>
{
const
index
=
children
?.
findIndex
((
node
)
=>
String
(
node
?.[
attribute
])
===
String
(
value
))
const
index
=
children
?.
findIndex
((
node
)
=>
String
(
node
?.[
attribute
])
===
String
(
value
))
return
index
>=
0
?
[
index
]
:
null
return
index
>=
0
?
[
index
]
:
null
...
...
apps/admin/src/components/editor/wangeditor-customer/shell/editor-config.js
浏览文件 @
be72dcaa
...
@@ -99,6 +99,20 @@ export const createEditorConfig = ({ onFocus, onContentChange }) => ({
...
@@ -99,6 +99,20 @@ export const createEditorConfig = ({ onFocus, onContentChange }) => ({
image
:
{
image
:
{
menuKeys
:
[
'imageWidth30'
,
'imageWidth50'
,
'imageWidth100'
,
'ImageEditor'
,
'deleteImage'
],
menuKeys
:
[
'imageWidth30'
,
'imageWidth50'
,
'imageWidth100'
,
'ImageEditor'
,
'deleteImage'
],
},
},
table
:
{
menuKeys
:
[
'enter'
,
'tableHeader'
,
'tableFullWidth'
,
'insertTableRow'
,
'insertTableRowAfter'
,
'deleteTableRow'
,
'insertTableCol'
,
'insertTableColAfter'
,
'deleteTableCol'
,
'deleteTable'
,
],
},
ImageAuto
:
{
ImageAuto
:
{
menuKeys
:
[
menuKeys
:
[
'imageWidthChpater100'
,
'imageWidthChpater100'
,
...
...
apps/admin/vite.config.js
浏览文件 @
be72dcaa
import
{
fileURLToPath
,
URL
}
from
'node:url'
import
{
fileURLToPath
,
URL
}
from
'node:url'
import
{
defineConfig
}
from
'vite'
import
{
defineConfig
}
from
'vite'
import
react
from
'@vitejs/plugin-react'
import
react
from
'@vitejs/plugin-react'
import
mkcert
from
'vite-plugin-mkcert'
import
mkcert
from
'vite-plugin-mkcert'
// https://vitejs.dev/config/
// https://vitejs.dev/config/
export
default
defineConfig
(()
=>
{
export
default
defineConfig
(()
=>
{
return
{
return
{
base
:
'/admin/'
,
base
:
'/admin/'
,
plugins
:
[
react
(),
mkcert
()],
plugins
:
[
react
(),
mkcert
()],
...
@@ -13,30 +13,30 @@ export default defineConfig(() => {
...
@@ -13,30 +13,30 @@ export default defineConfig(() => {
open
:
'/admin/'
,
open
:
'/admin/'
,
host
:
'dev.ezijing.com'
,
host
:
'dev.ezijing.com'
,
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/qwen'
:
{
'/api/qwen'
:
{
target
:
'https://dashscope.aliyuncs.com'
,
target
:
'https://dashscope.aliyuncs.com'
,
changeOrigin
:
true
,
changeOrigin
:
true
,
rewrite
:
path
=>
path
.
replace
(
/^
\/
api
\/
qwen/
,
''
),
rewrite
:
(
path
)
=>
path
.
replace
(
/^
\/
api
\/
qwen/
,
''
),
},
},
'/api/qianfan'
:
{
'/api/qianfan'
:
{
target
:
'https://aip.baidubce.com'
,
target
:
'https://aip.baidubce.com'
,
changeOrigin
:
true
,
changeOrigin
:
true
,
rewrite
:
path
=>
path
.
replace
(
/^
\/
api
\/
qianfan/
,
''
),
rewrite
:
(
path
)
=>
path
.
replace
(
/^
\/
api
\/
qianfan/
,
''
),
},
},
'/api/deepseek'
:
{
'/api/deepseek'
:
{
target
:
'https://api.deepseek.com'
,
target
:
'https://api.deepseek.com'
,
changeOrigin
:
true
,
changeOrigin
:
true
,
rewrite
:
path
=>
path
.
replace
(
/^
\/
api
\/
deepseek/
,
''
),
rewrite
:
(
path
)
=>
path
.
replace
(
/^
\/
api
\/
deepseek/
,
''
),
},
},
},
},
},
},
build
:
{
build
:
{
outDir
:
'../../dist/admin'
,
outDir
:
'../../dist/admin'
,
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论