Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
pptist
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
viitto
pptist
Commits
4921f3e0
Commit
4921f3e0
authored
Nov 30, 2023
by
zhengke
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
上传行程特色图到站点
parent
debf28bb
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
297 additions
and
69 deletions
+297
-69
axiosUpload.ts
src/configs/axiosUpload.ts
+122
-0
useExport.ts
src/hooks/useExport.ts
+3
-6
UploadService.ts
src/services/UploadService.ts
+16
-0
domainManager.ts
src/utils/domainManager.ts
+11
-0
requestUpload.ts
src/utils/requestUpload.ts
+25
-0
index.vue
src/views/Editor/Canvas/index.vue
+79
-3
index.vue
src/views/Editor/EditorHeader/index.vue
+40
-60
index.vue
src/views/Editor/index.vue
+1
-0
No files found.
src/configs/axiosUpload.ts
0 → 100644
View file @
4921f3e0
import
Axios
,
{
AxiosResponse
,
InternalAxiosRequestConfig
,
AxiosError
,
}
from
'axios'
;
import
{
domainManager
}
from
'../utils/domainManager'
let
datas
:
AxiosResponse
export
enum
ApiResult
{
'SUCCESS'
=
1
,
'FAILED'
=
0
,
'TOKEN_INVALID'
=
10000
,
'TOKEN_ILLEGAL'
=
10001
,
}
/**
* get status code
* @param {AxiosResponse} response Axios response object
*/
const
getErrorCode2text
=
(
response
:
AxiosResponse
):
string
=>
{
const
code
=
response
.
status
let
message
=
'Request Error'
switch
(
code
)
{
case
400
:
message
=
'Request Error'
break
case
401
:
message
=
'Unauthorized, please login'
break
case
403
:
message
=
'拒绝访问'
break
case
404
:
message
=
'访问资源不存在'
break
case
408
:
message
=
'请求超时'
break
case
500
:
message
=
'位置错误'
break
case
501
:
message
=
'承载服务未实现'
break
case
502
:
message
=
'网关错误'
break
case
503
:
message
=
'服务暂不可用'
break
case
504
:
message
=
'网关超时'
break
case
505
:
message
=
'暂不支持的 HTTP 版本'
break
default
:
message
=
'位置错误'
}
return
message
}
/**
* @returns {AxiosResponse} result
* @tutorial see more:https://github.com/onlyling/some-demo/tree/master/typescript-width-axios
* @example
* service.get<{data: string; code: number}>('/test').then(({data}) => { console.log(data.code) })
*/
const
service
=
Axios
.
create
({
baseURL
:
domainManager
().
UploadUrl
,
timeout
:
20000
,
headers
:
{
"Content-Type"
:
"application/x-www-form-urlencoded;"
}
})
/**
* @description 请求发起前的拦截器
* @returns {AxiosRequestConfig} config
*/
service
.
interceptors
.
request
.
use
(
async
(
config
:
InternalAxiosRequestConfig
)
=>
{
return
config
;
},
error
=>
{
//TODO: 新增网络请求异常处理业务
return
Promise
.
reject
(
error
)
}
)
/**
* @description 响应收到后的拦截器
* @returns {}
*/
service
.
interceptors
.
response
.
use
(
/** 请求有响应 */
async
(
response
:
AxiosResponse
)
=>
{
if
(
response
.
status
===
200
)
{
if
(
response
.
data
.
resultCode
==
ApiResult
.
TOKEN_ILLEGAL
||
response
.
data
.
resultCode
==
ApiResult
.
TOKEN_INVALID
){
}
datas
=
response
return
Promise
.
resolve
(
datas
)
}
else
{
const
__text
=
getErrorCode2text
(
response
)
return
Promise
.
reject
(
new
Error
(
__text
))
}
},
/** 请求无响应 */
(
error
:
AxiosError
)
=>
{
if
(
error
&&
error
.
response
)
{
const
__text
=
getErrorCode2text
(
error
.
response
);
return
Promise
.
reject
(
new
Error
(
__text
));
}
else
{
return
Promise
.
reject
(
new
Error
(
'unknow error'
));
}
}
)
export
default
service
src/hooks/useExport.ts
View file @
4921f3e0
...
...
@@ -50,12 +50,9 @@ export default () => {
index
:
i
,
url
:
dataUrl
}
// eslint-disable-next-line eqeqeq
const
objData
=
FeatureImg
.
value
.
find
(
(
x
:
{
index
:
number
})
=>
{
return
x
.
index
==
i
}
)
if
(
!
objData
)
{
FeatureImg
.
value
.
push
(
obj
)
FeatureImgStore
.
setFeatureImg
(
JSON
.
parse
(
JSON
.
stringify
(
FeatureImg
.
value
)))
}
FeatureImg
.
value
.
push
(
obj
)
FeatureImgStore
.
setFeatureImg
(
JSON
.
parse
(
JSON
.
stringify
(
FeatureImg
.
value
)))
}).
catch
(()
=>
{
message
.
error
(
'导出图片失败'
)
})
...
...
src/services/UploadService.ts
0 → 100644
View file @
4921f3e0
import
Api
,{
HttpResponse
,
Result
}
from
'./../utils/requestUpload'
;
import
{
domainManager
}
from
'./../utils/domainManager'
/**
* 配置相关方法
*/
class
UploadService
{
/**
* base64Str上传
*/
static
async
UploadBase64Two
(
path
:
any
,
params
:
any
):
Promise
<
HttpResponse
>
{
let
apiurl
=
`
${
domainManager
().
UploadUrl
}
/Upload/UploadBase64
${
path
}
`
return
Api
.
Post
(
apiurl
,
params
)
}
}
export
default
UploadService
;
\ No newline at end of file
src/utils/domainManager.ts
0 → 100644
View file @
4921f3e0
export
const
domainManager
=
()
=>
{
const
locationName
=
window
.
location
.
hostname
const
obj
=
{
domainUrl
:
locationName
.
indexOf
(
'oytour'
)
!==
-
1
||
locationName
.
indexOf
(
'viitto'
)
!==
-
1
?
"http://upload.oytour.com"
:
"http://192.168.10.214/api/common/post"
,
//上传站点
UploadUrl
:
locationName
.
indexOf
(
'oytour'
)
!==
-
1
||
locationName
.
indexOf
(
'viitto'
)
!==
-
1
?
"http://upload.oytour.com"
:
"http://192.168.10.214:8120"
,
//文件站点
ViittoFileUrl
:
locationName
.
indexOf
(
'oytour'
)
!==
-
1
||
locationName
.
indexOf
(
'viitto'
)
!==
-
1
?
"http://imgfile.oytour.com/"
:
'http://192.168.10.214:8130/'
,
}
return
obj
}
\ No newline at end of file
src/utils/requestUpload.ts
0 → 100644
View file @
4921f3e0
import
service
,
{
ApiResult
}
from
"../configs/axiosUpload"
;
import
{
userStore
}
from
"@/store/user"
;
import
md5
from
"md5-ts"
;
export
interface
HttpResponse
{
status
:
number
statusText
:
string
data
:
Result
}
export
interface
Result
{
resultCode
:
ApiResult
message
:
string
data
:
any
[
key
:
string
]:
any
}
class
Api
{
constructor
(){
}
static
Post
=
(
path
:
string
,
base64Str
:
any
):
Promise
<
HttpResponse
>=>
{
return
service
.
post
(
path
,
base64Str
)
}
}
export
default
Api
;
src/views/Editor/Canvas/index.vue
View file @
4921f3e0
...
...
@@ -94,19 +94,37 @@
<LinkDialog
@
close=
"linkDialogVisible = false"
/>
</Modal>
</div>
<div
style=
"position: relative;z-index: -1;"
>
<div
class=
"export-img-dialog"
>
<div
class=
"thumbnails-view"
>
<div
class=
"thumbnails"
v-for=
"slide in slides"
ref=
"FeatureImgRef"
>
<ThumbnailSlide
class=
"thumbnail"
:key=
"slide.id"
:slide=
"slide"
:size=
"1600"
/>
</div>
</div>
</div>
</div>
</
template
>
<
script
lang=
"ts"
setup
>
import
{
nextTick
,
onMounted
,
onUnmounted
,
provide
,
ref
,
watch
,
watchEff
ect
}
from
'vue'
import
{
nextTick
,
onMounted
,
onUnmounted
,
provide
,
ref
,
reactive
,
watch
,
watchEffect
,
computed
,
inj
ect
}
from
'vue'
import
{
throttle
}
from
'lodash'
import
{
storeToRefs
}
from
'pinia'
import
{
useMainStore
,
useSlidesStore
,
useKeyboardStore
}
from
'@/store'
import
{
useMainStore
,
useSlidesStore
,
useKeyboardStore
,
useScreenStore
}
from
'@/store'
import
type
{
ContextmenuItem
}
from
'@/components/Contextmenu/types'
import
type
{
PPTElement
}
from
'@/types/slides'
import
type
{
AlignmentLineProps
,
CreateCustomShapeData
}
from
'@/types/edit'
import
{
injectKeySlideScale
}
from
'@/types/injectKey'
import
{
removeAllRanges
}
from
'@/utils/selection'
import
{
KEYS
}
from
'@/configs/hotkey'
import
useExport
from
'@/hooks/useExport'
import
UploadService
from
'@/services/UploadService'
import
{
injectKeyDataSource
}
from
'@/types/injectKey'
import
{
domainManager
}
from
'../../../utils/domainManager'
import
useViewportSize
from
'./hooks/useViewportSize'
import
useMouseSelection
from
'./hooks/useMouseSelection'
...
...
@@ -138,6 +156,7 @@ import MultiSelectOperate from './Operate/MultiSelectOperate.vue'
import
Operate
from
'./Operate/index.vue'
import
LinkDialog
from
'./LinkDialog.vue'
import
Modal
from
'@/components/Modal.vue'
import
ThumbnailSlide
from
'@/views/components/ThumbnailSlide/index.vue'
const
mainStore
=
useMainStore
()
const
{
...
...
@@ -153,12 +172,52 @@ const {
canvasScale
,
textFormatPainter
,
}
=
storeToRefs
(
mainStore
)
const
{
currentSlide
}
=
storeToRefs
(
useSlidesStore
())
const
{
currentSlide
,
slides
}
=
storeToRefs
(
useSlidesStore
())
const
{
ctrlKeyState
,
spaceKeyState
}
=
storeToRefs
(
useKeyboardStore
())
const
viewportRef
=
ref
<
HTMLElement
>
()
const
alignmentLines
=
ref
<
AlignmentLineProps
[]
>
([])
const
{
exportFeatureImg
}
=
useExport
()
const
datas
=
reactive
({
FeatureImgList
:
[],
loading
:
false
})
datas
.
FeatureImgList
=
inject
(
injectKeyDataSource
).
FeatureImgList
const
FeatureImgStore
=
useScreenStore
()
const
{
market
,
model
,
ConfigId
,
CoverImg
,
dataLoading
,
FeatureImg
}
=
storeToRefs
(
useScreenStore
())
const
renderSlides
=
computed
(()
=>
{
return
slides
.
value
})
const
FeatureImgRef
=
ref
(
null
)
// 将界面生成形成图
watch
(()
=>
slides
.
value
,
(
n
,
o
)
=>
{
FeatureImgStore
.
setFeatureImg
([])
setTimeout
(()
=>
{
for
(
let
i
=
0
;
i
<
FeatureImgRef
.
value
.
length
;
i
++
){
exportFeatureImg
(
FeatureImgRef
.
value
[
i
],
'jpeg'
,
1
,
true
,
i
+
1
)
}
},
500
)
})
// 监听请求保存成功 重新请求数据
watch
(()
=>
FeatureImgRef
.
value
,
(
n
,
o
)
=>
{
})
watch
(()
=>
FeatureImg
.
value
,
(
n
,
o
)
=>
{
FeatureImg
.
value
.
sort
((
a
,
b
)
=>
{
return
a
.
index
-
b
.
index
})
if
(
FeatureImg
.
value
.
length
==
slides
.
value
.
length
){
FeatureImg
.
value
.
forEach
(
item
=>
{
setTimeout
(()
=>
{
setFeatureImg
(
item
.
url
)
},
300
)
})
}
})
const
linkDialogVisible
=
ref
(
false
)
const
openLinkDialog
=
()
=>
linkDialogVisible
.
value
=
true
...
...
@@ -201,6 +260,23 @@ onMounted(() => {
}
})
// 上传文件
const
setFeatureImg
=
async
(
url
)
=>
{
// if(!ConfigId.value) return
try
{
let
queryObj
=
{
MyFile
:
url
}
let
path
=
`?fileType=1&fileLimit=5&&filePath=Feature/
${
ConfigId
.
value
}
_`
let
Res
=
await
UploadService
.
UploadBase64Two
(
path
,
queryObj
);
if
(
Res
.
data
&&
Res
.
data
.
FilePath
)
{
console
.
log
(
`
${
domainManager
().
ViittoFileUrl
}${
Res
.
data
.
FilePath
}
`
,
'====Res.data'
)
datas
.
FeatureImgList
.
push
(
`
${
domainManager
().
ViittoFileUrl
}${
Res
.
data
.
FilePath
}
`
)
}
}
catch
(
error
)
{
}
}
// 点击画布的空白区域:清空焦点元素、设置画布焦点、清除文字选区、清空格式刷状态
const
handleClickBlankArea
=
(
e
:
MouseEvent
)
=>
{
console
.
log
(
e
.
button
)
...
...
src/views/Editor/EditorHeader/index.vue
View file @
4921f3e0
...
...
@@ -78,12 +78,6 @@
</
template
>
</el-button>
<div>
<!-- <template v-for="item in datas.DataSource.FeatureImg">
<img :src="item.url" style="width: 50px;height: 50px;" />
</template> -->
<!-- <template v-for="item in datas.DataSource.FeatureImg">
<img :src="item" style="width: 50px;height: 50px;" />
</template> -->
</div>
<!-- <a class="github-link" href="https://github.com/pipipi-pikachu/PPTist" target="_blank">
<div class="menu-item"><IconGithub class="icon" /></div>
...
...
@@ -101,20 +95,7 @@
<FullscreenSpin
:loading=
"exporting"
tip=
"正在导入..."
/>
<Psd-Upload
:visible=
"psdVisibleStatus"
@
closed=
"psdVisibleStatus=false"
></Psd-Upload>
</div>
<div
style=
"position: relative;z-index: -1;"
>
<div
class=
"export-img-dialog"
>
<div
class=
"thumbnails-view"
>
<div
class=
"thumbnails"
v-for=
"slide in renderSlides"
ref=
"FeatureImgRef"
>
<ThumbnailSlide
class=
"thumbnail"
:key=
"slide.id"
:slide=
"slide"
:size=
"1600"
/>
</div>
</div>
</div>
</div>
</template>
...
...
@@ -134,7 +115,7 @@ import ConfigService from '@/services/ConfigService'
import
{
injectKeyDataSource
,
injectKeyTemplate
}
from
'@/types/injectKey'
import
PsdUpload
from
'@/components/PSD/Index.vue'
import
{
svg2Base64
}
from
'@/utils/svg2Base64'
import
useExport
from
'@/hooks/useExport'
import
HotkeyDoc
from
'./HotkeyDoc.vue'
...
...
@@ -144,7 +125,7 @@ import Drawer from '@/components/Drawer.vue'
import
Input
from
'@/components/Input.vue'
import
Popover
from
'@/components/Popover.vue'
import
PopoverMenuItem
from
'@/components/PopoverMenuItem.vue'
import
ThumbnailSlide
from
'@/views/components/ThumbnailSlide/index.vue'
const
mainStore
=
useMainStore
()
const
slidesStore
=
useSlidesStore
()
...
...
@@ -176,17 +157,9 @@ searchData.value = inject(injectKeyTemplate)
const
marketStore
=
useScreenStore
()
const
CoverImgStore
=
useScreenStore
()
const
dataLoadingStore
=
useScreenStore
()
const
FeatureImgStore
=
useScreenStore
()
const
psdVisibleStatus
=
ref
(
false
)
const
{
market
,
model
,
ConfigId
,
CoverImg
,
dataLoading
,
FeatureImg
}
=
storeToRefs
(
useScreenStore
())
const
renderSlides
=
computed
(()
=>
{
return
slides
.
value
})
const
{
exportFeatureImg
}
=
useExport
()
const
FeatureImgRef
=
ref
(
null
)
const
psdVisibleStatus
=
ref
(
false
)
const
{
market
,
model
,
ConfigId
,
CoverImg
,
dataLoading
}
=
storeToRefs
(
useScreenStore
())
// 返回到首页
const
goBack
=
()
=>
{
...
...
@@ -235,29 +208,6 @@ const UploadPsdHandler = () => {
psdVisibleStatus
.
value
=
true
}
// 监听请求保存成功 重新请求数据
watch
(()
=>
FeatureImgRef
.
value
,
(
n
,
o
)
=>
{
if
(
FeatureImgRef
.
value
.
length
==
renderSlides
.
value
.
length
){
FeatureImgStore
.
setFeatureImg
([])
for
(
let
i
=
0
;
i
<
FeatureImgRef
.
value
.
length
;
i
++
){
exportFeatureImg
(
FeatureImgRef
.
value
[
i
],
'jpeg'
,
1
,
true
,
i
+
1
)
}
}
})
watch
(()
=>
FeatureImg
.
value
,
(
n
,
o
)
=>
{
FeatureImg
.
value
.
sort
((
a
,
b
)
=>
{
return
a
.
index
-
b
.
index
})
datas
.
DataSource
.
FeatureImg
=
FeatureImg
.
value
.
map
(
x
=>
{
return
x
.
url
}
)
})
watch
(()
=>
slides
.
value
,
(
n
,
o
)
=>
{
if
(
ConfigId
.
value
&&
FeatureImgRef
.
value
.
length
==
renderSlides
.
value
.
length
){
FeatureImgStore
.
setFeatureImg
([])
for
(
let
i
=
0
;
i
<
FeatureImgRef
.
value
.
length
;
i
++
){
exportFeatureImg
(
FeatureImgRef
.
value
[
i
],
'jpeg'
,
1
,
true
,
i
+
1
)
}
}
})
// 新增修改模版
const
SetTripTemplateSlide
=
async
()
=>
{
// console.log(JSON.parse(queryObj.value.TempData),'--------')
...
...
@@ -265,13 +215,27 @@ const SetTripTemplateSlide = async () => {
console
.
log
(
queryObj
.
value
,
'新增修改模版---'
)
let
TemplateRes
=
await
ConfigService
.
SetTripTemplateSlide
(
queryObj
.
value
);
if
(
TemplateRes
.
data
.
resultCode
==
1
)
{
ElMessage
({
showClose
:
true
,
message
:
'操作成功'
,
type
:
'success'
,
})
dataLoadingStore
.
setDataLoading
(
true
)
}
else
{
ElMessage
({
showClose
:
true
,
message
:
'操作失败'
,
type
:
'warning'
,
})
}
dataLoadingStore
.
setDataLoading
(
true
)
datas
.
loading
=
false
}
catch
(
error
)
{
datas
.
loading
=
false
console
.
log
(
"TemplateGetTripFiled"
,
error
);
ElMessage
({
showClose
:
true
,
message
:
'操作失败'
,
type
:
'warning'
,
})
}
}
// 用户新增修改数据
...
...
@@ -281,17 +245,32 @@ const SetTripTemplateConfig = async () => {
ConfigId
:
ConfigId
.
value
,
TempId
:
queryObj
.
value
.
TempId
,
TempData
:
queryObj
.
value
.
TempData
,
FeatureImg
:
datas
.
DataSource
.
FeatureImg
FeatureImg
:
datas
.
DataSource
.
FeatureImg
List
}
let
TemplateRes
=
await
ConfigService
.
SetSetTripConfig
(
queryMsg
);
if
(
TemplateRes
.
data
.
resultCode
==
1
)
{
ElMessage
({
showClose
:
true
,
message
:
'操作成功'
,
type
:
'success'
,
})
FeatureImgStore
.
setFeatureImg
([])
dataLoadingStore
.
setDataLoading
(
true
)
}
else
{
ElMessage
({
showClose
:
true
,
message
:
'操作失败'
,
type
:
'warning'
,
})
}
datas
.
loading
=
false
}
catch
(
error
)
{
datas
.
loading
=
false
console
.
log
(
"TemplateGetTripFiled"
,
error
);
ElMessage
({
showClose
:
true
,
message
:
'操作失败'
,
type
:
'warning'
,
})
}
}
// 保存
...
...
@@ -343,6 +322,7 @@ const setTemplate = async () =>{
// }
// }
}
console
.
log
(
queryObj
.
value
,
'-------'
)
queryObj
.
value
.
TempData
=
JSON
.
stringify
(
slides
.
value
)
datas
.
loading
=
true
if
(
model
.
value
&&
userInfo
.
value
.
IsEditTripTemplate
==
1
){
...
...
src/views/Editor/index.vue
View file @
4921f3e0
...
...
@@ -53,6 +53,7 @@ import ConfigService from '@/services/ConfigService'
const
datas
=
reactive
({
DataSource
:{
FeatureImgList
:
[],
ConfigId
:
inject
(
injectKeyTemplate
).
ConfigId
?
inject
(
injectKeyTemplate
).
ConfigId
:
0
,
pageType
:
1
,
//1基础 2酒店 3景 4餐
DataSourceOverlay
:
false
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment