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
68c79bf1
Commit
68c79bf1
authored
Dec 06, 2023
by
zhengke
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
插入图片 替换图片
parent
e640fc2c
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
380 additions
and
9 deletions
+380
-9
ConfigService.ts
src/services/ConfigService.ts
+7
-0
screen.ts
src/store/screen.ts
+10
-0
UploadPicture.vue
src/views/Editor/CanvasTool/UploadPicture.vue
+329
-0
index.vue
src/views/Editor/CanvasTool/index.vue
+18
-5
ImageStylePanel.vue
...iews/Editor/Toolbar/ElementStylePanel/ImageStylePanel.vue
+16
-4
No files found.
src/services/ConfigService.ts
View file @
68c79bf1
...
...
@@ -60,5 +60,12 @@ class ConfigService{
static
async
GetTemplagePageAsync
(
params
:
any
):
Promise
<
HttpResponse
>
{
return
Api
.
Post
(
"triptemplate_GetTripTemplatePage"
,
params
)
}
/**
* 图片素材分页列表
*/
static
async
GetPicList
(
params
:
any
):
Promise
<
HttpResponse
>
{
return
Api
.
Post
(
"hotel_post_GetPicList"
,
params
)
}
}
export
default
ConfigService
;
\ No newline at end of file
src/store/screen.ts
View file @
68c79bf1
...
...
@@ -16,6 +16,8 @@ export interface ScreenState {
FeatureImg
:
any
,
SourceLoading
:
boolean
,
pageIndex
:
number
,
imgPoolVisible
:
boolean
,
imgReplaceVisible
:
boolean
,
}
export
const
useScreenStore
=
defineStore
(
'screen'
,
{
...
...
@@ -34,6 +36,8 @@ export const useScreenStore = defineStore('screen', {
FeatureImg
:
[],
// 行程特色图
SourceLoading
:
false
,
// 记录数据源是否更改
pageIndex
:
0
,
//需要生成图的行程特色
imgPoolVisible
:
false
,
//新增上传图片弹窗
imgReplaceVisible
:
false
,
//替换图片弹窗
}),
actions
:
{
...
...
@@ -81,6 +85,12 @@ export const useScreenStore = defineStore('screen', {
},
setPageIndex
(
pageIndex
:
number
){
this
.
pageIndex
=
pageIndex
},
setImgPoolVisible
(
imgPoolVisible
:
boolean
)
{
this
.
imgPoolVisible
=
imgPoolVisible
},
setImgReplaceVisible
(
imgReplaceVisible
:
boolean
)
{
this
.
imgReplaceVisible
=
imgReplaceVisible
}
},
})
\ No newline at end of file
src/views/Editor/CanvasTool/UploadPicture.vue
0 → 100644
View file @
68c79bf1
<
template
>
<el-dialog
v-model=
"showVisible"
:show-close=
"false"
:close-on-press-escape=
"false"
:close-on-click-modal=
"false"
style=
"width: 680px;"
>
<template
#
header
>
<div
class=
"text-title"
>
选择、上传添加图片
</div>
</
template
>
<el-tabs
v-model=
"activeName"
class=
"demo-tabs"
@
tab-click=
"handleClick"
>
<el-tab-pane
label=
"选择图"
name=
"1"
>
<div
class=
"q-mb-md"
>
<el-input
v-model=
"datas.queryMsg.Name"
placeholder=
"输入关键字快速查找"
clearable
class=
"input-with-select"
>
<
template
#
append
>
<el-button
type=
"primary"
@
click=
"SearchHandler"
>
搜索
</el-button>
</
template
>
</el-input>
</div>
<div
class=
"row UploadPicture-box"
v-loading=
"datas.loading"
>
<div
v-for=
"(item,index) in datas.imgList"
class=
"UploadPicture-list"
>
<div
class=
"UploadPicture-listBox"
>
<img
:src=
"item.Path"
class=
"rounded"
@
click=
"getImgs(item,index)"
/>
<div
class=
"UploadPicture-Hover"
v-if=
"item.show"
>
<div>
<el-icon
:size=
"20"
><CircleCheckFilled/></el-icon>
</div>
</div>
</div>
</div>
</div>
<div
class=
"q-mt-md"
style=
"display: flex;justify-content: center;"
>
<el-pagination
v-model:current-page=
"currentPage"
:page-size=
"datas.queryMsg.pageSize"
:small=
"small"
:disabled=
"disabled"
:background=
"background"
layout=
"prev, pager, next"
:total=
"datas.queryMsg.total"
@
size-change=
"handleSizeChange"
@
current-change=
"handleCurrentChange"
/>
</div>
</el-tab-pane>
<el-tab-pane
label=
"上传图"
name=
"2"
>
<FileInput
@
change=
"files => insertImageElement(files)"
>
<div
class=
"upload-box"
>
<img
v-if=
"imgPath"
:src=
"imgPath"
style=
"height: 200px;"
/>
<div
v-else
>
<el-icon
size=
"80"
color=
"#a8abb2"
class=
"el-icon--upload"
>
<upload-filled/>
</el-icon>
<p><em>
点击上传图片
</em></p>
</div>
</div>
</FileInput>
<!--
<div>
<el-upload
v-loading="isUpload"
ref="upload"
class="upload-drop-box"
:on-change="handleChange"
action=""
drag
:limit="1"
:on-exceed="handleExceed"
:auto-upload="false"
accept=".png,.jpg"
:show-file-list="false"
>
<el-icon v-if="!imgPath" class="el-icon--upload">
<upload-filled />
</el-icon>
<div v-if="!imgPath" class="el-upload__text">
<template>
拖动文件到这里释放或<em>点击上传</em>
</template>
</div>
<template #tip>
</template>
</el-upload>
</div> -->
</el-tab-pane>
<el-tab-pane
label=
"输入url"
name=
"3"
>
<div
class=
"row wrap q-mt-md"
>
<el-input
v-model=
"imgUrl"
placeholder=
"输入图片的url地址"
class=
"input-with-select"
></el-input>
</div>
</el-tab-pane>
</el-tabs>
<div
class=
"q-mt-lg row items-center"
>
<div
class=
"col"
>
</div>
<div>
<el-button
class=
"q-ml-lg"
@
click=
"close()"
>
取消
</el-button>
<el-button
type=
"primary"
class=
"q-ml-lg"
@
click=
"setImgs()"
>
确定
</el-button>
</div>
</div>
</el-dialog>
</template>
<
script
lang=
"ts"
setup
>
import
{
ref
,
reactive
,
inject
}
from
'vue'
import
{
storeToRefs
}
from
'pinia'
import
type
{
UploadProps
,
UploadUserFile
,
UploadInstance
}
from
'element-plus'
import
useCreateElement
from
'@/hooks/useCreateElement'
import
useHistorySnapshot
from
'@/hooks/useHistorySnapshot'
import
{
getImageDataURL
}
from
'@/utils/image'
import
{
useMainStore
,
useSlidesStore
,
useScreenStore
}
from
'@/store'
import
{
injectKeyDataSource
}
from
'@/types/injectKey'
import
ConfigService
from
'@/services/ConfigService'
import
FileInput
from
'@/components/FileInput.vue'
const
showVisible
=
ref
(
true
)
const
activeName
=
ref
(
"1"
)
const
imgPoolVisibleStore
=
useScreenStore
()
const
imgReplaceVisibleStore
=
useScreenStore
()
const
imageFile
=
ref
({})
const
isUpload
=
ref
(
false
)
const
imgOnline
=
ref
(
''
)
const
imgPath
=
ref
(
''
)
const
imgUrl
=
ref
(
''
)
const
currentPage
=
ref
(
1
)
const
upload
=
ref
<
UploadInstance
>
()
const
imgType
=
ref
(
0
)
// 1 插入图片 2替换图片
imgType
.
value
=
inject
(
'imgType'
)
const
propsDatas
=
ref
({
src
:
''
})
const
datas
=
reactive
({
DataSource
:{},
loading
:
false
,
imgList
:
[],
queryMsg
:{
pageSize
:
16
,
pageIndex
:
1
,
currentPage
:
1
,
total
:
0
,
Type
:
0
,
//1-酒店,2-餐厅,3-景点,4-票务,5-车辆,6-领队,7-购物店
Name
:
""
,
//资源图片名称
SourceId
:
0
//资源编号
}
})
datas
.
DataSource
=
inject
(
injectKeyDataSource
)
if
(
datas
.
DataSource
.
pageType
==
2
)
datas
.
queryMsg
.
Type
=
1
else
if
(
datas
.
DataSource
.
pageType
==
3
)
datas
.
queryMsg
.
Type
=
3
else
if
(
datas
.
DataSource
.
pageType
==
4
)
datas
.
queryMsg
.
Type
=
2
const
mainStore
=
useMainStore
()
const
{
createImageElement
}
=
useCreateElement
()
const
{
addHistorySnapshot
}
=
useHistorySnapshot
()
const
slidesStore
=
useSlidesStore
()
const
{
handleElement
,
handleElementId
}
=
storeToRefs
(
mainStore
)
const
handleSizeChange
=
(
val
:
number
)
=>
{
console
.
log
(
`
${
val
}
items per page`
)
}
const
handleCurrentChange
=
(
val
:
number
)
=>
{
datas
.
queryMsg
.
pageIndex
=
val
getImgList
()
}
const
insertImageElement
=
(
files
:
FileList
)
=>
{
const
imageFile
=
files
[
0
]
if
(
!
imageFile
)
return
getImageDataURL
(
imageFile
).
then
(
dataURL
=>
imgPath
.
value
=
dataURL
,
propsDatas
.
value
=
{
src
:
dataURL
}
// createImageElement(dataURL)
)
}
const
setImgs
=
()
=>
{
let
text
=
'请选择图片'
let
url
=
imgOnline
.
value
const
props
=
{
url
:
url
}
if
(
activeName
.
value
==
'1'
)
propsDatas
.
value
=
{
src
:
imgOnline
.
value
}
else
if
(
activeName
.
value
==
'2'
)
{
text
=
'请上传图片'
url
=
imgPath
.
value
}
else
if
(
activeName
.
value
==
'3'
)
{
text
=
'请输入图片url地址'
url
=
imgUrl
.
value
propsDatas
.
value
=
{
src
:
imgUrl
.
value
}
}
if
(
!
url
){
return
ElMessage
({
showClose
:
true
,
message
:
text
,
type
:
'warning'
,
})
}
if
(
imgType
.
value
==
1
){
createImageElement
(
url
)
close
()
}
if
(
imgType
.
value
==
2
){
slidesStore
.
updateElement
({
id
:
handleElementId
.
value
,
props
:
propsDatas
.
value
})
addHistorySnapshot
()
close
()
}
}
const
getImgs
=
(
item
:
any
,
index
:
number
)
=>
{
datas
.
imgList
.
forEach
(
x
=>
{
x
.
show
=
false
})
item
.
show
=
true
imgOnline
.
value
=
item
.
Path
}
const
handleClick
=
(
tab
:
TabsPaneContext
,
event
:
Event
)
=>
{
if
(
activeName
.
value
!=
'1'
){
imgOnline
.
value
=
''
datas
.
imgList
.
forEach
(
x
=>
{
x
.
show
=
false
})
}
else
if
(
activeName
.
value
!=
'2'
){
imgPath
.
value
=
''
imageFile
.
value
=
{}
}
else
if
(
activeName
.
value
!=
'3'
){
imgUrl
.
value
=
''
}
}
const
close
=
()
=>
{
// imgOnline.value = ''
// datas.imgList.forEach(x=>{x.show=false})
// imgPath.value = ''
// imageFile.value = {}
// imgUrl.value = ''
showVisible
.
value
=
false
imgPoolVisibleStore
.
setImgPoolVisible
(
false
)
imgReplaceVisibleStore
.
setImgReplaceVisible
(
false
)
}
const
SearchHandler
=
async
()
=>
{
datas
.
queryMsg
.
pageIndex
=
1
await
getImgList
()
}
const
getImgList
=
async
()
=>
{
datas
.
loading
=
true
try
{
let
datasRes
=
await
ConfigService
.
GetPicList
(
datas
.
queryMsg
);
if
(
datasRes
.
data
.
resultCode
==
1
)
{
let
data
=
datasRes
.
data
.
data
.
pageData
let
arrData
=
function
(
list
){
list
.
forEach
(
item
=>
{
item
.
show
=
false
});
}
arrData
(
data
)
datas
.
imgList
=
data
datas
.
queryMsg
.
total
=
datasRes
.
data
.
data
.
count
;
}
datas
.
loading
=
false
}
catch
(
error
)
{
datas
.
loading
=
false
}
}
const
handleChange
:
UploadProps
[
'onChange'
]
=
(
uploadFile
,
uploadFiles
)
=>
{
isUpload
.
value
=
true
console
.
log
(
uploadFile
,
'---------'
)
if
(
uploadFile
){
imageFile
.
value
=
uploadFile
imgPath
.
value
=
URL
.
createObjectURL
(
uploadFile
?.
raw
)
isUpload
.
value
=
false
}
}
const
handleExceed
:
UploadProps
[
'onExceed'
]
=
(
files
)
=>
{
console
.
log
(
'执行clear'
)
upload
.
value
!
.
clearFiles
()
const
file
=
files
[
0
]
as
UploadRawFile
upload
.
value
!
.
handleStart
(
file
)
}
getImgList
()
</
script
>
<
style
lang=
"scss"
scoped
>
.upload-box
{
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
text-align
:
center
;
border
:
1px
dashed
#dcdfe6
;
border-radius
:
6px
;
padding
:
40px
10px
;
cursor
:
pointer
;
}
.UploadPicture-box
{
flex-wrap
:
wrap
;
}
.UploadPicture-list
{
width
:
150px
;
/* height: 150px; */
margin
:
5px
;
}
.UploadPicture-listBox
{
width
:
150px
;
height
:
0
;
position
:
relative
;
padding-bottom
:
56
.25%
;
}
.UploadPicture-list
img
{
width
:
100%
;
height
:
100%
;
position
:
absolute
;
object-fit
:
cover
;
cursor
:
pointer
;
}
.UploadPicture-Hover
{
z-index
:
1
;
position
:
absolute
;
top
:
0
;
left
:
0
;
right
:
0
;
bottom
:
0
;
background
:
rgba
(
23
,
23
,
23
,
0
.5
);
/* opacity: 0; */
display
:
none
;
transition
:
opacity
0
.5s
ease
;
display
:
flex
;
flex-direction
:
column
;
justify-content
:
center
;
align-items
:
center
;
color
:
$themeHoverColor
;
}
</
style
>
\ No newline at end of file
src/views/Editor/CanvasTool/index.vue
View file @
68c79bf1
...
...
@@ -20,9 +20,10 @@
<IconDown
class=
"arrow"
/>
</Popover>
</div>
<FileInput
@
change=
"files => insertImageElement(files)"
>
<IconPicture
class=
"handler-item"
v-tooltip=
"'插入图片'"
/>
</FileInput>
<!-- <FileInput @change="files => insertImageElement(files)">
<IconPicture class="handler-item" v-tooltip="'插入图片'" />
</FileInput> imgPoolVisible-->
<IconPicture
class=
"handler-item"
v-tooltip=
"'插入图片'"
@
click=
"getImgVis()"
/>
<Popover
trigger=
"click"
v-model:value=
"shapePoolVisible"
>
<
template
#
content
>
<ShapePool
@
select=
"shape => drawShape(shape)"
/>
...
...
@@ -89,13 +90,16 @@
@
update=
"data => { createLatexElement(data); latexEditorVisible = false }"
/>
</Modal>
<!-- 上传图片 -->
<UploadPicture
v-if=
"imgPoolVisible"
></UploadPicture>
</div>
</template>
<
script
lang=
"ts"
setup
>
import
{
ref
}
from
'vue'
import
{
ref
,
provide
}
from
'vue'
import
{
storeToRefs
}
from
'pinia'
import
{
useMainStore
,
useSnapshotStore
}
from
'@/store'
import
{
useMainStore
,
useSnapshotStore
,
useScreenStore
}
from
'@/store'
import
{
getImageDataURL
}
from
'@/utils/image'
import
type
{
ShapePoolItem
}
from
'@/configs/shapes'
import
type
{
LinePoolItem
}
from
'@/configs/lines'
...
...
@@ -114,6 +118,7 @@ import Modal from '@/components/Modal.vue'
import
Divider
from
'@/components/Divider.vue'
import
Popover
from
'@/components/Popover.vue'
import
PopoverMenuItem
from
'@/components/PopoverMenuItem.vue'
import
UploadPicture
from
'./UploadPicture.vue'
const
mainStore
=
useMainStore
()
const
{
creatingElement
,
creatingCustomShape
,
showSelectPanel
,
showSearchPanel
}
=
storeToRefs
(
mainStore
)
...
...
@@ -121,6 +126,8 @@ const { canUndo, canRedo } = storeToRefs(useSnapshotStore())
const
{
redo
,
undo
}
=
useHistorySnapshot
()
const
{
imgPoolVisible
}
=
storeToRefs
(
useScreenStore
())
const
{
scaleCanvas
,
setCanvasScalePercentage
,
...
...
@@ -145,6 +152,8 @@ const {
createAudioElement
,
}
=
useCreateElement
()
provide
(
'imgType'
,
1
)
const
insertImageElement
=
(
files
:
FileList
)
=>
{
const
imageFile
=
files
[
0
]
if
(
!
imageFile
)
return
...
...
@@ -159,6 +168,10 @@ const mediaInputVisible = ref(false)
const
latexEditorVisible
=
ref
(
false
)
const
textTypeSelectVisible
=
ref
(
false
)
const
getImgVis
=
()
=>
{
imgPoolVisible
.
value
=
true
}
// 绘制文字范围
const
drawText
=
(
vertical
=
false
)
=>
{
mainStore
.
setCreatingElement
({
...
...
src/views/Editor/Toolbar/ElementStylePanel/ImageStylePanel.vue
View file @
68c79bf1
...
...
@@ -50,19 +50,22 @@
<Divider
/>
<ElementShadow
/>
<Divider
/>
<!--
<FileInput @change="files => replaceImage(files)">
<Button class="full-width-btn"><IconTransform class="btn-icon" /> 替换图片</Button>
</FileInput>
</FileInput> -->
<Button
class=
"full-width-btn"
@
click=
"getImgVis()"
><IconTransform
class=
"btn-icon"
/>
替换图片
</Button>
<Button
class=
"full-width-btn"
@
click=
"resetImage()"
><IconUndo
class=
"btn-icon"
/>
重置样式
</Button>
<Button
class=
"full-width-btn"
@
click=
"setBackgroundImage()"
><IconTheme
class=
"btn-icon"
/>
设为背景
</Button>
<!-- 上传图片 -->
<UploadPicture
v-if=
"imgReplaceVisible"
></UploadPicture>
</div>
</template>
<
script
lang=
"ts"
setup
>
import
{
type
Ref
,
ref
}
from
'vue'
import
{
type
Ref
,
ref
,
provide
}
from
'vue'
import
{
storeToRefs
}
from
'pinia'
import
{
useMainStore
,
useSlidesStore
}
from
'@/store'
import
{
useMainStore
,
useSlidesStore
,
useScreenStore
}
from
'@/store'
import
type
{
PPTImageElement
,
SlideBackground
}
from
'@/types/slides'
import
{
CLIPPATHS
}
from
'@/configs/imageClip'
import
{
getImageDataURL
}
from
'@/utils/image'
...
...
@@ -78,6 +81,7 @@ import Divider from '@/components/Divider.vue'
import
Button
from
'@/components/Button.vue'
import
ButtonGroup
from
'@/components/ButtonGroup.vue'
import
Popover
from
'@/components/Popover.vue'
import
UploadPicture
from
'../../CanvasTool/UploadPicture.vue'
const
shapeClipPathOptions
=
CLIPPATHS
const
ratioClipOptions
=
[
...
...
@@ -124,6 +128,14 @@ const clipPanelVisible = ref(false)
const
{
addHistorySnapshot
}
=
useHistorySnapshot
()
const
{
imgReplaceVisible
}
=
storeToRefs
(
useScreenStore
())
provide
(
'imgType'
,
2
)
const
getImgVis
=
()
=>
{
imgReplaceVisible
.
value
=
true
}
// 打开自由裁剪
const
clipImage
=
()
=>
{
mainStore
.
setClipingImageElementId
(
handleElementId
.
value
)
...
...
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