Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
C
center-book
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
EzijingWeb
center-book
Commits
89d5a908
提交
89d5a908
authored
8月 31, 2026
作者:
王鹏飞
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: 优化上传逻辑,添加成功提示信息,调整 API 调用方式
上级
a46dc4da
显示空白字符变更
内嵌
并排
正在显示
20 个修改的文件
包含
192 行增加
和
43 行删除
+192
-43
upload-progress.test.ts
...tor/wangeditor-customer/__tests__/upload-progress.test.ts
+12
-5
ExpandReadDialog.jsx
...editor-customer/features/expand-read/ExpandReadDialog.jsx
+4
-2
GalleryDialog.jsx
...or/wangeditor-customer/features/gallery/GalleryDialog.jsx
+15
-1
node.js
...ents/editor/wangeditor-customer/features/practice/node.js
+2
-0
TooltipDialog.jsx
...or/wangeditor-customer/features/tooltip/TooltipDialog.jsx
+1
-0
VideoDialog.jsx
...editor/wangeditor-customer/features/video/VideoDialog.jsx
+0
-2
index.jsx
apps/admin/src/components/selectTeacher/index.jsx
+12
-2
api.ts
apps/admin/src/modules/account/api.ts
+5
-2
api.js
apps/admin/src/modules/books/management/chapters/api.js
+2
-2
form-chapter-title.jsx
...oks/management/chapters/components/form-chapter-title.jsx
+2
-1
index.jsx
apps/admin/src/modules/books/management/chapters/index.jsx
+34
-1
index.less
apps/admin/src/modules/books/management/chapters/index.less
+7
-0
index.test.tsx
...dmin/src/modules/books/management/chapters/index.test.tsx
+68
-6
api.ts
apps/admin/src/modules/settings/applied/api.ts
+2
-2
api.ts
apps/admin/src/modules/settings/coupon/api.ts
+5
-3
HelpAddEditView.jsx
...admin/src/modules/settings/help/views/HelpAddEditView.jsx
+1
-3
api.ts
apps/admin/src/modules/settings/point-management/api.ts
+4
-1
axios.ts
apps/admin/src/utils/axios.ts
+2
-1
oss.js
apps/admin/src/utils/oss.js
+7
-2
vite.config.js
apps/admin/vite.config.js
+7
-7
没有找到文件。
apps/admin/src/components/editor/wangeditor-customer/__tests__/upload-progress.test.ts
浏览文件 @
89d5a908
...
...
@@ -71,13 +71,20 @@ describe('OSS upload progress', () => {
client
.
generateObjectUrl
.
mockReturnValue
(
'https://example.com/video.mp4'
)
const
onProgress
=
vi
.
fn
()
await
expect
(
uploadFile
({
name
:
'video.mp4'
},
{
onProgress
,
parallel
:
3
,
retries
:
3
})
,
)
.
resolves
.
toBe
(
'https://example.com/video.mp4'
)
await
expect
(
uploadFile
({
name
:
'video.mp4'
},
{
onProgress
})).
resolves
.
toBe
(
'https://example.com/video.mp4'
,
)
expect
(
client
.
multipartUpload
).
toHaveBeenCalledTimes
(
2
)
expect
(
client
.
multipartUpload
.
mock
.
calls
[
0
][
2
]).
toMatchObject
({
parallel
:
3
})
expect
(
client
.
multipartUpload
.
mock
.
calls
[
1
][
2
]).
toMatchObject
({
checkpoint
,
parallel
:
3
})
expect
(
client
.
multipartUpload
.
mock
.
calls
[
0
][
2
]).
toMatchObject
({
partSize
:
4
*
1024
*
1024
,
parallel
:
3
,
})
expect
(
client
.
multipartUpload
.
mock
.
calls
[
1
][
2
]).
toMatchObject
({
checkpoint
,
partSize
:
4
*
1024
*
1024
,
parallel
:
3
,
})
expect
(
onProgress
.
mock
.
calls
.
map
(([
percent
])
=>
percent
)).
toEqual
([
50
,
100
])
})
})
apps/admin/src/components/editor/wangeditor-customer/features/expand-read/ExpandReadDialog.jsx
浏览文件 @
89d5a908
...
...
@@ -122,13 +122,14 @@ const ExpandModal = (props, ref) => {
SlateTransforms
.
insertNodes
(
editor
,
nextNode
,
{
at
:
existingPath
})
}
const
data
=
await
addExpandRead
({
await
addExpandRead
({
book_id
:
bookId
,
chapter_id
:
chapterId
,
position
:
nowRandom
,
type
:
flex
,
...
other
,
})
message
.
success
(
'扩展阅读更新成功'
)
setNowRandom
(
null
)
setExpandVisible
(
false
)
setLoadLoading
(
false
)
...
...
@@ -136,13 +137,14 @@ const ExpandModal = (props, ref) => {
}
const
random
=
Math
.
random
().
toString
(
10
).
substring
(
2
,
10
)
const
data
=
await
addExpandRead
({
await
addExpandRead
({
book_id
:
bookId
,
chapter_id
:
chapterId
,
position
:
random
,
type
:
flex
,
...
other
,
})
message
.
success
(
'扩展阅读添加成功'
)
editor
.
restoreSelection
()
if
(
parseInt
(
values
.
flex
)
===
1
)
{
...
...
apps/admin/src/components/editor/wangeditor-customer/features/gallery/GalleryDialog.jsx
浏览文件 @
89d5a908
import
{
useState
,
useEffect
,
forwardRef
}
from
'react'
import
{
Divider
,
Input
,
Space
,
Button
,
Form
,
ColorPicker
,
Tabs
,
Select
,
Row
,
Col
}
from
'antd'
import
{
Divider
,
Input
,
Space
,
Button
,
Form
,
ColorPicker
,
Tabs
,
Select
,
Row
,
Col
,
message
,
}
from
'antd'
import
'../../index.less'
import
{
addGallery
}
from
'../../shared/request'
import
{
SlateTransforms
}
from
'@wangeditor/editor'
...
...
@@ -230,6 +242,7 @@ const GalleryModal = (props, ref) => {
content
:
JSON
.
stringify
(
gallery
),
position
:
nowRandom
,
})
message
.
success
(
'画廊更新成功'
)
if
(
flex
===
2
)
{
const
aPath
=
findNodeWithParent
(
...
...
@@ -260,6 +273,7 @@ const GalleryModal = (props, ref) => {
content
:
JSON
.
stringify
(
gallery
),
position
:
random
,
})
message
.
success
(
'画廊添加成功'
)
editor
.
restoreSelection
()
if
(
parseInt
(
flex
)
!==
2
)
{
removeSelectedEmptyParagraph
(
editor
,
SlateTransforms
)
...
...
apps/admin/src/components/editor/wangeditor-customer/features/practice/node.js
浏览文件 @
89d5a908
import
{
DomEditor
,
SlateTransforms
}
from
'@wangeditor/editor'
import
{
h
}
from
'snabbdom'
import
{
message
}
from
'antd'
import
{
openEditorDialog
}
from
'../../core/editor-dialog'
import
iconClose
from
'@/assets/images/icon_chapter_close.png'
import
{
delChapterTopic
}
from
'../../shared/request'
...
...
@@ -127,6 +128,7 @@ const renderPractice = (elem, children, editor) => {
book_id
:
bookId
,
chapter_id
:
chapterId
,
})
message
.
success
(
'题目删除成功'
)
try
{
const
path
=
findNodeWithParent
(
...
...
apps/admin/src/components/editor/wangeditor-customer/features/tooltip/TooltipDialog.jsx
浏览文件 @
89d5a908
...
...
@@ -142,6 +142,7 @@ const TooltipModal = (props, ref) => {
chapter_id
:
chapterId
,
position
:
nowRandom
,
})
message
.
success
(
'气泡删除成功'
)
if
(
data
)
{
editor
.
restoreSelection
()
const
nodeEntries
=
SlateEditor
.
nodes
(
editor
,
{
...
...
apps/admin/src/components/editor/wangeditor-customer/features/video/VideoDialog.jsx
浏览文件 @
89d5a908
...
...
@@ -50,8 +50,6 @@ const VideoModal = ({ open, onClose, payload = {}, runtime }) => {
setUploadProgress
(
0
)
try
{
const
url
=
await
uploadFile
(
file
,
{
parallel
:
3
,
retries
:
3
,
onProgress
:
(
percent
)
=>
{
setUploadProgress
(
percent
)
onProgress
?.({
percent
})
...
...
apps/admin/src/components/selectTeacher/index.jsx
浏览文件 @
89d5a908
...
...
@@ -12,13 +12,17 @@ function DebounceSelect({ fetchOptions, debounceTimeout = 800, ...props }) {
const
fetchId
=
fetchRef
.
current
setOptions
([])
setFetching
(
true
)
fetchOptions
(
value
).
then
((
newOptions
)
=>
{
fetchOptions
(
value
)
.
then
((
newOptions
)
=>
{
if
(
fetchId
!==
fetchRef
.
current
)
{
// for fetch callback order
return
}
setOptions
(
newOptions
)
setFetching
(
false
)
})
.
catch
(()
=>
undefined
)
.
finally
(()
=>
{
if
(
fetchId
===
fetchRef
.
current
)
setFetching
(
false
)
})
}
return
debounce
(
loadOptions
,
debounceTimeout
)
...
...
@@ -29,6 +33,12 @@ function DebounceSelect({ fetchOptions, debounceTimeout = 800, ...props }) {
showSearch=
{
{
filterOption
:
false
,
onSearch
:
debounceFetcher
}
}
notFoundContent=
{
fetching
?
<
Spin
size=
'small'
/>
:
null
}
{
...
props
}
onOpenChange=
{
(
open
)
=>
{
if
(
open
)
{
debounceFetcher
(
''
)
debounceFetcher
.
flush
()
}
}
}
options=
{
options
}
/>
)
...
...
apps/admin/src/modules/account/api.ts
浏览文件 @
89d5a908
...
...
@@ -3,8 +3,11 @@ import axios, { notifySuccess } from '@/utils/axios'
export
const
getUserInfo
=
async
(
params
)
=>
(
await
axios
.
post
(
'/api/admin/user/user/getUserInfo'
,
params
)).
data
export
const
changePass
=
async
(
params
)
=>
(
await
axios
.
post
(
'/api/admin/user/user/changePass'
,
params
)).
data
export
const
changePass
=
async
(
params
)
=>
{
const
response
=
await
axios
.
post
(
'/api/admin/user/user/changePass'
,
params
)
notifySuccess
(
response
.
message
)
return
response
.
data
}
export
const
changeInfo
=
async
(
params
)
=>
{
const
response
=
await
axios
.
post
(
'/api/admin/user/user/editUserInfo'
,
params
)
...
...
apps/admin/src/modules/books/management/chapters/api.js
浏览文件 @
89d5a908
...
...
@@ -71,13 +71,13 @@ export const getAllList = async (params) => {
export
const
chapterAdd
=
(
params
)
=>
getData
(
'/api/admin/book/teacher/chapter/add'
,
params
)
export
const
getInfoById
=
(
params
)
=>
getData
(
'/api/admin/book/teacher/chapter/getInfoById'
,
params
)
export
const
chapterEdit
=
(
params
)
=>
mutate
(
'/api/admin/book/teacher/chapter/edit'
,
params
,
true
)
export
const
chapterEdit
=
(
params
)
=>
mutate
(
'/api/admin/book/teacher/chapter/edit'
,
params
)
export
const
chapterDel
=
(
params
)
=>
mutate
(
'/api/admin/book/teacher/chapter/del'
,
params
,
true
)
export
const
dragOrder
=
(
params
)
=>
mutate
(
'/api/admin/book/teacher/chapter/dragOrder'
,
params
,
true
)
export
const
getInfoByChapterId
=
(
params
)
=>
getData
(
'/api/admin/book/teacher/section/getInfoByChapterId'
,
params
)
export
const
sectionAdd
=
(
params
)
=>
mutate
(
'/api/admin/book/teacher/section/add'
,
params
,
true
)
export
const
sectionAdd
=
(
params
)
=>
mutate
(
'/api/admin/book/teacher/section/add'
,
params
)
export
const
sectionEdit
=
(
params
)
=>
mutate
(
'/api/admin/book/teacher/section/edit'
,
params
)
export
const
getQuestionList
=
(
params
)
=>
getData
(
'/api/admin/book/chapter/question/getQuestionList'
,
params
)
...
...
apps/admin/src/modules/books/management/chapters/components/form-chapter-title.jsx
浏览文件 @
89d5a908
import
{
useState
,
useEffect
,
useRef
}
from
'react'
import
{
Form
,
Button
,
Space
,
Input
}
from
'antd'
import
{
Form
,
Button
,
Space
,
Input
,
message
}
from
'antd'
import
{
useUserStore
}
from
'@/stores/userStore'
import
{
chapterEdit
,
chapterAdd
,
sectionAdd
}
from
'../api'
...
...
@@ -57,6 +57,7 @@ const EditChapterTitle = (props) => {
if
(
parentId
)
{
await
sectionAdd
({
book_id
:
bookId
,
chapter_id
:
data
.
id
,
content
:
''
,
word_count
:
0
})
}
message
.
success
(
parentId
?
'章节创建成功'
:
'章节更新成功'
)
setEditKey
(
false
)
setEditValue
(
null
)
await
getChapterTreeList
()
...
...
apps/admin/src/modules/books/management/chapters/index.jsx
浏览文件 @
89d5a908
import
{
useState
,
useEffect
,
useRef
,
useCallback
}
from
'react'
import
{
Button
,
Row
,
Col
,
Descriptions
,
Tree
,
Dropdown
,
Modal
,
Spin
,
App
,
Tooltip
}
from
'antd'
import
{
Button
,
Row
,
Col
,
Descriptions
,
Tree
,
Dropdown
,
Modal
,
Spin
,
App
,
Tooltip
,
Empty
,
}
from
'antd'
import
{
EllipsisOutlined
,
DiffOutlined
,
...
...
@@ -134,6 +146,18 @@ const Examine = () => {
}
if
(
data
.
length
===
0
)
{
chapterRequestRef
.
current
+=
1
setGData
([])
setExpandedKeys
([])
setCheckedKeys
([])
setChapterId
(
0
)
setNowTitle
(
''
)
setHtml
(
''
)
setContentId
(
false
)
setLoadedChapterId
(
0
)
setChapterLoadFailed
(
false
)
contentMd5Ref
.
current
=
md5
(
''
)
setTreeChapter
({
saveBookId
:
id
,
saveChapterId
:
null
})
setLoading
(
false
)
return
}
...
...
@@ -538,6 +562,15 @@ const Examine = () => {
<
div
className=
'book-content-editor'
style=
{
{
flex
:
1
,
minWidth
:
0
}
}
>
<
div
className=
'editor-right'
>
<
Spin
spinning=
{
loading
}
>
{
!
loading
&&
gData
.
length
===
0
&&
(
<
Empty
className=
'chapter-empty'
description=
'暂无章节'
>
{
isAdminOrCreator
&&
(
<
Button
type=
'primary'
onClick=
{
addChapterParent
}
>
新增第一个章节
</
Button
>
)
}
</
Empty
>
)
}
{
editorReady
&&
(
<
WangEditorCustomer
key=
{
chapterId
}
...
...
apps/admin/src/modules/books/management/chapters/index.less
浏览文件 @
89d5a908
...
...
@@ -92,6 +92,13 @@
gap: 12px;
color: #6f7886;
}
.chapter-empty {
display: flex;
height: 100%;
flex-direction: column;
align-items: center;
justify-content: center;
}
}
.draggable-tree {
flex: 1;
...
...
apps/admin/src/modules/books/management/chapters/index.test.tsx
浏览文件 @
89d5a908
import
{
act
,
fireEvent
,
render
,
screen
,
waitFor
}
from
'@testing-library/react'
import
{
act
,
cleanup
,
fireEvent
,
render
,
screen
,
waitFor
}
from
'@testing-library/react'
import
type
{
ComponentProps
,
ReactNode
}
from
'react'
import
{
beforeEach
,
describe
,
expect
,
it
,
vi
}
from
'vitest'
import
{
afterEach
,
beforeEach
,
describe
,
expect
,
it
,
vi
}
from
'vitest'
import
Examine
from
'./index'
const
mocks
=
vi
.
hoisted
(()
=>
({
chapterDel
:
vi
.
fn
(),
confirm
:
vi
.
fn
(),
getAllList
:
vi
.
fn
(),
getInfoByChapterId
:
vi
.
fn
(),
sectionEdit
:
vi
.
fn
(),
...
...
@@ -16,7 +18,7 @@ vi.mock('antd', () => {
const
PassThrough
=
({
children
}:
{
children
?:
ReactNode
})
=>
<>
{
children
}
</>
return
{
App
:
{
useApp
:
()
=>
({
modal
:
{
confirm
:
vi
.
fn
()
}
})
},
App
:
{
useApp
:
()
=>
({
modal
:
{
confirm
:
mocks
.
confirm
}
})
},
Button
:
({
children
,
onClick
,
...
props
}:
ComponentProps
<
'button'
>
)
=>
(
<
button
onClick=
{
onClick
}
{
...
props
}
>
{
children
}
...
...
@@ -30,7 +32,34 @@ vi.mock('antd', () => {
))
}
</>
),
Dropdown
:
PassThrough
,
Dropdown
:
({
children
,
menu
,
}:
{
children
?:
ReactNode
menu
?:
{
items
?:
Array
<
{
key
:
string
;
label
:
string
}
>
onClick
:
(
event
:
{
key
:
string
;
domEvent
:
{
stopPropagation
:
()
=>
void
}
})
=>
void
}
})
=>
(
<>
{
children
}
{
menu
?.
items
?.
map
((
item
:
{
key
:
string
;
label
:
string
})
=>
(
<
button
key=
{
item
.
key
}
onClick=
{
()
=>
menu
.
onClick
({
key
:
item
.
key
,
domEvent
:
{
stopPropagation
:
vi
.
fn
()
}
})
}
>
{
item
.
label
}
</
button
>
))
}
</>
),
Empty
:
({
children
,
description
}:
{
children
?:
ReactNode
;
description
?:
ReactNode
})
=>
(
<
div
>
{
description
}
{
children
}
</
div
>
),
Modal
:
({
children
,
open
}:
{
children
?:
ReactNode
;
open
?:
boolean
})
=>
open
?
<>
{
children
}
</>
:
null
,
Row
:
PassThrough
,
...
...
@@ -39,17 +68,22 @@ vi.mock('antd', () => {
Tree
:
({
disabled
,
onSelect
,
titleRender
,
treeData
=
[],
}:
{
disabled
?:
boolean
onSelect
:
(
keys
:
number
[],
info
:
{
node
:
{
key
:
number
;
title
:
string
}
})
=>
void
titleRender
?:
(
node
:
{
key
:
number
;
title
:
string
})
=>
ReactNode
treeData
?:
Array
<
{
key
:
number
;
title
:
string
}
>
})
=>
(
<
div
>
{
treeData
.
map
((
node
)
=>
(
<
button
key=
{
node
.
key
}
disabled=
{
disabled
}
onClick=
{
()
=>
onSelect
([
node
.
key
],
{
node
})
}
>
<
div
key=
{
node
.
key
}
>
<
button
disabled=
{
disabled
}
onClick=
{
()
=>
onSelect
([
node
.
key
],
{
node
})
}
>
{
node
.
title
}
</
button
>
{
titleRender
?.(
node
)
}
</
div
>
))
}
</
div
>
),
...
...
@@ -115,7 +149,7 @@ vi.mock('@/utils/common', () => ({
}))
vi
.
mock
(
'./api'
,
()
=>
({
chapterDel
:
vi
.
fn
()
,
chapterDel
:
mocks
.
chapterDel
,
dragOrder
:
vi
.
fn
(),
getAllList
:
mocks
.
getAllList
,
getInfoByChapterId
:
mocks
.
getInfoByChapterId
,
...
...
@@ -135,8 +169,12 @@ const deferred = <T,>() => {
}
describe('chapter editor lifecycle', () =
>
{
afterEach
(
cleanup
)
beforeEach
(()
=>
{
vi
.
clearAllMocks
()
mocks
.
chapterDel
.
mockResolvedValue
(
true
)
mocks
.
confirm
.
mockImplementation
(({
onOk
})
=>
onOk
())
mocks
.
getAllList
.
mockResolvedValue
({
code
:
200
,
data
:
[
...
...
@@ -188,4 +226,28 @@ describe('chapter editor lifecycle', () => {
expect
(
secondEditor
).
toHaveAttribute
(
'data-chapter-id'
,
'2'
)
expect
(
secondEditor
).
toHaveAttribute
(
'data-html'
,
'<p>章节二内容</p>'
)
})
it
(
'clears the last chapter and shows an empty state after deletion'
,
async
()
=>
{
mocks
.
getAllList
.
mockResolvedValueOnce
({
code
:
200
,
data
:
[{
id
:
1
,
name
:
'章节一'
}]
})
.
mockResolvedValueOnce
({
code
:
200
,
data
:
[]
})
mocks
.
getInfoByChapterId
.
mockResolvedValue
({
id
:
101
,
content
:
'<p>章节一内容</p>'
,
selected_editor_ids
:
[
1
],
})
render
(<
Examine
/>)
expect
(
await
screen
.
findByTestId
(
'chapter-editor'
)).
toBeInTheDocument
()
fireEvent
.
click
(
await
screen
.
findByRole
(
'button'
,
{
name
:
'删除'
}))
expect
(
await
screen
.
findByText
(
'暂无章节'
)).
toBeInTheDocument
()
expect
(
screen
.
queryByTestId
(
'chapter-editor'
)).
not
.
toBeInTheDocument
()
expect
(
screen
.
getByRole
(
'button'
,
{
name
:
'新增第一个章节'
})).
toBeInTheDocument
()
expect
(
mocks
.
setTreeChapter
).
toHaveBeenLastCalledWith
({
saveBookId
:
10
,
saveChapterId
:
null
,
})
})
}
)
apps/admin/src/modules/settings/applied/api.ts
浏览文件 @
89d5a908
...
...
@@ -10,6 +10,6 @@ const mutate = async (path, params, notify = false) => {
export
const
getAppList
=
(
params
)
=>
getData
(
'/api/admin/system/app/getList'
,
params
)
export
const
addApp
=
(
params
)
=>
mutate
(
'/api/admin/system/app/add'
,
params
,
true
)
export
const
getAppInfo
=
(
params
)
=>
getData
(
'/api/admin/system/app/getInfoById'
,
params
)
export
const
editApp
=
(
params
)
=>
getData
(
'/api/admin/system/app/edit'
,
params
)
export
const
changeStatus
=
(
params
)
=>
mutate
(
'/api/admin/system/app/changeStatus'
,
params
)
export
const
editApp
=
(
params
)
=>
mutate
(
'/api/admin/system/app/edit'
,
params
,
true
)
export
const
changeStatus
=
(
params
)
=>
mutate
(
'/api/admin/system/app/changeStatus'
,
params
,
true
)
export
const
delApp
=
(
params
)
=>
mutate
(
'/api/admin/system/app/del'
,
params
,
true
)
apps/admin/src/modules/settings/coupon/api.ts
浏览文件 @
89d5a908
import
{
message
}
from
'antd'
import
axios
from
'@/utils/axios'
import
axios
,
{
notifySuccess
}
from
'@/utils/axios'
import
type
{
CouponQuery
}
from
'./query'
...
...
@@ -47,8 +47,10 @@ export function editCoupon(data: object) {
return
axios
.
post
(
'/api/admin/system/coupon/edit'
,
data
)
}
export
function
deleteCoupon
(
data
:
object
)
{
return
axios
.
post
(
'/api/admin/system/coupon/del'
,
data
)
export
async
function
deleteCoupon
(
data
:
object
)
{
const
response
=
await
axios
.
post
(
'/api/admin/system/coupon/del'
,
data
)
notifySuccess
(
response
.
message
)
return
response
}
export
function
getCouponDetail
(
data
:
object
)
{
...
...
apps/admin/src/modules/settings/help/views/HelpAddEditView.jsx
浏览文件 @
89d5a908
...
...
@@ -145,12 +145,10 @@ const HelpAddEdit = () => {
// };
try
{
// message.success(`视频已上传:${uploadProgress}% , 玩命加载中~~`);
message
.
success
(
`视频已上传:99% , 正玩命加载中~~`
)
const
url
=
await
uploadFile
(
file
,
{
filenamePrefix
:
'help'
})
// insertFn(result.res.requestUrls[0], '题库视频');
insertFn
(
url
,
'题库视频'
)
message
.
success
(
'视频上传成功'
)
setLoading
(
false
)
}
catch
(
error
)
{
console
.
error
(
'上传视频失败:'
,
error
)
...
...
apps/admin/src/modules/settings/point-management/api.ts
浏览文件 @
89d5a908
...
...
@@ -35,7 +35,10 @@ export async function getPointSettings(): Promise<PointSettings> {
}
export
async
function
setPointSwitch
(
integralSwitch
:
'0'
|
'1'
)
{
await
axios
.
post
(
'/api/admin/system/config/integralSet'
,
{
integral_switch
:
integralSwitch
})
const
response
=
await
axios
.
post
(
'/api/admin/system/config/integralSet'
,
{
integral_switch
:
integralSwitch
,
})
notifySuccess
(
response
.
message
)
return
true
}
...
...
apps/admin/src/utils/axios.ts
浏览文件 @
89d5a908
...
...
@@ -143,7 +143,8 @@ httpRequest.interceptors.response.use(
console
.
error
(
`
${
status
}
:
${
data
?.
message
}
`)
}
} else {
console.log(error)
notification.error({ message: '网络请求失败,请稍后重试' })
console.error(error)
}
return Promise.reject(error.response || error)
},
...
...
apps/admin/src/utils/oss.js
浏览文件 @
89d5a908
...
...
@@ -58,14 +58,19 @@ export async function uploadFile(file, options = {}) {
const
objectName
=
buildObjectName
(
file
,
options
)
if
(
options
.
onProgress
)
{
const
retries
=
options
.
retries
??
0
const
{
partSize
=
4
*
1024
*
1024
,
parallel
=
3
,
retries
=
3
,
}
=
options
let
checkpoint
for
(
let
attempt
=
0
;
attempt
<=
retries
;
attempt
+=
1
)
{
try
{
const
result
=
await
oss
.
multipartUpload
(
objectName
,
file
,
{
checkpoint
,
parallel
:
options
.
parallel
,
partSize
,
parallel
,
progress
:
(
percentage
,
nextCheckpoint
)
=>
{
checkpoint
=
nextCheckpoint
||
checkpoint
options
.
onProgress
(
Math
.
round
(
percentage
*
100
))
...
...
apps/admin/vite.config.js
浏览文件 @
89d5a908
...
...
@@ -15,13 +15,13 @@ export default defineConfig(() => {
port
:
5174
,
strictPort
:
true
,
proxy
:
{
//
'/api/admin': {
//
target: 'http://127.0.0.1:7419',
//
changeOrigin: true,
//
secure: false,
//
rewrite: (path) => path.replace(/^\/api\/admin/, ''),
//
},
'/api'
:
'https://zijingebook.ezijing.com'
,
'/api/admin'
:
{
target
:
'http://127.0.0.1:7419'
,
changeOrigin
:
true
,
secure
:
false
,
rewrite
:
(
path
)
=>
path
.
replace
(
/^
\/
api
\/
admin/
,
''
),
},
//
'/api': 'https://zijingebook.ezijing.com',
},
},
build
:
{
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论