Browse Source
# Conflicts: # ruoyi-ui/src/views/cesiumMap/index.vue # ruoyi-ui/src/views/childRoom/index.vuemaster
8 changed files with 1033 additions and 118 deletions
@ -0,0 +1,172 @@ |
|||||
|
<template> |
||||
|
<el-dialog |
||||
|
title="选择图标" |
||||
|
:visible.sync="dialogVisible" |
||||
|
width="600px" |
||||
|
:modal="true" |
||||
|
:close-on-click-modal="false" |
||||
|
:close-on-press-escape="false" |
||||
|
class="icon-select-dialog" |
||||
|
> |
||||
|
<div class="icon-grid"> |
||||
|
<div |
||||
|
v-for="item in availableIcons" |
||||
|
:key="item.id" |
||||
|
class="icon-item" |
||||
|
:class="{ selected: selectedIcons.includes(item.id) }" |
||||
|
@click="toggleIcon(item)" |
||||
|
> |
||||
|
<i :class="item.icon"></i> |
||||
|
<span class="icon-name">{{ item.name }}</span> |
||||
|
<div v-if="selectedIcons.includes(item.id)" class="check-icon"> |
||||
|
<i class="el-icon-check"></i> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<span slot="footer" class="dialog-footer"> |
||||
|
<el-button @click="dialogVisible = false" size="small">取消</el-button> |
||||
|
<el-button type="primary" @click="confirmAdd" size="small">确定</el-button> |
||||
|
</span> |
||||
|
</el-dialog> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'IconSelectDialog', |
||||
|
props: { |
||||
|
visible: { |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
availableIcons: { |
||||
|
type: Array, |
||||
|
default: () => [] |
||||
|
}, |
||||
|
existingIcons: { |
||||
|
type: Array, |
||||
|
default: () => [] |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
selectedIcons: [] |
||||
|
} |
||||
|
}, |
||||
|
computed: { |
||||
|
dialogVisible: { |
||||
|
get() { |
||||
|
return this.visible |
||||
|
}, |
||||
|
set(val) { |
||||
|
this.$emit('update:visible', val) |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
watch: { |
||||
|
visible(newVal) { |
||||
|
if (newVal) { |
||||
|
this.selectedIcons = [] |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
toggleIcon(item) { |
||||
|
const index = this.selectedIcons.indexOf(item.id) |
||||
|
if (index > -1) { |
||||
|
this.selectedIcons.splice(index, 1) |
||||
|
} else { |
||||
|
this.selectedIcons.push(item.id) |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
confirmAdd() { |
||||
|
const selectedItems = this.availableIcons.filter(item => |
||||
|
this.selectedIcons.includes(item.id) |
||||
|
) |
||||
|
this.$emit('confirm', selectedItems) |
||||
|
this.dialogVisible = false |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.icon-select-dialog >>> .el-dialog__body { |
||||
|
padding: 20px; |
||||
|
} |
||||
|
|
||||
|
.icon-grid { |
||||
|
display: grid; |
||||
|
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); |
||||
|
gap: 15px; |
||||
|
max-height: 400px; |
||||
|
overflow-y: auto; |
||||
|
} |
||||
|
|
||||
|
.icon-item { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
padding: 15px 10px; |
||||
|
border: 2px solid #E4E7ED; |
||||
|
border-radius: 8px; |
||||
|
cursor: pointer; |
||||
|
transition: all 0.3s; |
||||
|
position: relative; |
||||
|
background: white; |
||||
|
} |
||||
|
|
||||
|
.icon-item:hover { |
||||
|
border-color: #008aff; |
||||
|
background: rgba(0, 138, 255, 0.05); |
||||
|
transform: translateY(-2px); |
||||
|
box-shadow: 0 4px 12px rgba(0, 138, 255, 0.15); |
||||
|
} |
||||
|
|
||||
|
.icon-item.selected { |
||||
|
border-color: #008aff; |
||||
|
background: rgba(0, 138, 255, 0.1); |
||||
|
} |
||||
|
|
||||
|
.icon-item i { |
||||
|
font-size: 28px; |
||||
|
color: #555; |
||||
|
margin-bottom: 8px; |
||||
|
transition: color 0.3s; |
||||
|
} |
||||
|
|
||||
|
.icon-item:hover i, |
||||
|
.icon-item.selected i { |
||||
|
color: #008aff; |
||||
|
} |
||||
|
|
||||
|
.icon-name { |
||||
|
font-size: 12px; |
||||
|
color: #606266; |
||||
|
text-align: center; |
||||
|
word-break: break-all; |
||||
|
} |
||||
|
|
||||
|
.check-icon { |
||||
|
position: absolute; |
||||
|
top: 5px; |
||||
|
right: 5px; |
||||
|
width: 20px; |
||||
|
height: 20px; |
||||
|
border: 2px solid #008aff; |
||||
|
border-radius: 50%; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
color: #008aff; |
||||
|
font-size: 12px; |
||||
|
} |
||||
|
|
||||
|
.dialog-footer { |
||||
|
display: flex; |
||||
|
justify-content: flex-end; |
||||
|
gap: 10px; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,197 @@ |
|||||
|
<template> |
||||
|
<div v-if="value" class="page-layout-dialog"> |
||||
|
<div class="dialog-content"> |
||||
|
<div class="dialog-header"> |
||||
|
<h3>页面布局</h3> |
||||
|
<div class="close-btn" @click="closeDialog">×</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="dialog-body"> |
||||
|
<div class="position-options"> |
||||
|
<div |
||||
|
v-for="option in positionOptions" |
||||
|
:key="option.value" |
||||
|
class="position-option" |
||||
|
:class="{ active: selectedPosition === option.value }" |
||||
|
@click="selectPosition(option.value)" |
||||
|
> |
||||
|
<i :class="option.icon"></i> |
||||
|
<span>{{ option.label }}</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="dialog-footer"> |
||||
|
<el-button @click="closeDialog" size="small">取消</el-button> |
||||
|
<el-button type="primary" @click="saveLayout" size="small">确定</el-button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'PageLayoutDialog', |
||||
|
props: { |
||||
|
value: { |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
selectedPosition: 'left', |
||||
|
positionOptions: [ |
||||
|
{ value: 'top', label: '顶部', icon: 'el-icon-top' }, |
||||
|
{ value: 'bottom', label: '底部', icon: 'el-icon-bottom' }, |
||||
|
{ value: 'left', label: '左侧', icon: 'el-icon-back' }, |
||||
|
{ value: 'right', label: '右侧', icon: 'el-icon-right' } |
||||
|
] |
||||
|
}; |
||||
|
}, |
||||
|
watch: { |
||||
|
value(newVal) { |
||||
|
if (newVal) { |
||||
|
this.selectedPosition = this.$parent.menuPosition || 'left'; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
selectPosition(position) { |
||||
|
this.selectedPosition = position; |
||||
|
}, |
||||
|
closeDialog() { |
||||
|
this.$emit('input', false); |
||||
|
}, |
||||
|
saveLayout() { |
||||
|
this.$emit('save', this.selectedPosition); |
||||
|
this.closeDialog(); |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.page-layout-dialog { |
||||
|
position: fixed; |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
right: 0; |
||||
|
bottom: 0; |
||||
|
z-index: 1000; |
||||
|
display: flex; |
||||
|
align-items: flex-start; |
||||
|
justify-content: center; |
||||
|
padding-top: 100px; |
||||
|
pointer-events: none; |
||||
|
} |
||||
|
|
||||
|
.dialog-content { |
||||
|
position: relative; |
||||
|
background: white; |
||||
|
border-radius: 8px; |
||||
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15); |
||||
|
width: 300px; |
||||
|
animation: dialog-fade-in 0.3s ease; |
||||
|
pointer-events: auto; |
||||
|
} |
||||
|
|
||||
|
@keyframes dialog-fade-in { |
||||
|
from { |
||||
|
opacity: 0; |
||||
|
transform: translateY(-20px); |
||||
|
} |
||||
|
to { |
||||
|
opacity: 1; |
||||
|
transform: translateY(0); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.dialog-header { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: space-between; |
||||
|
padding: 12px 16px; |
||||
|
border-bottom: 1px solid #e8e8e8; |
||||
|
} |
||||
|
|
||||
|
.dialog-header h3 { |
||||
|
margin: 0; |
||||
|
font-size: 14px; |
||||
|
font-weight: 600; |
||||
|
color: #333; |
||||
|
} |
||||
|
|
||||
|
.close-btn { |
||||
|
font-size: 18px; |
||||
|
color: #999; |
||||
|
cursor: pointer; |
||||
|
transition: color 0.3s; |
||||
|
line-height: 1; |
||||
|
} |
||||
|
|
||||
|
.close-btn:hover { |
||||
|
color: #666; |
||||
|
} |
||||
|
|
||||
|
.dialog-body { |
||||
|
padding: 16px; |
||||
|
} |
||||
|
|
||||
|
.position-options { |
||||
|
display: grid; |
||||
|
grid-template-columns: repeat(2, 1fr); |
||||
|
gap: 10px; |
||||
|
} |
||||
|
|
||||
|
.position-option { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
padding: 15px 10px; |
||||
|
border: 1px solid #e8e8e8; |
||||
|
border-radius: 6px; |
||||
|
cursor: pointer; |
||||
|
transition: all 0.3s; |
||||
|
background: white; |
||||
|
} |
||||
|
|
||||
|
.position-option:hover { |
||||
|
border-color: #008aff; |
||||
|
background: rgba(0, 138, 255, 0.05); |
||||
|
transform: translateY(-2px); |
||||
|
box-shadow: 0 2px 8px rgba(0, 138, 255, 0.15); |
||||
|
} |
||||
|
|
||||
|
.position-option.active { |
||||
|
border-color: #008aff; |
||||
|
background: rgba(0, 138, 255, 0.1); |
||||
|
} |
||||
|
|
||||
|
.position-option i { |
||||
|
font-size: 24px; |
||||
|
color: #555; |
||||
|
margin-bottom: 6px; |
||||
|
transition: color 0.3s; |
||||
|
} |
||||
|
|
||||
|
.position-option:hover i, |
||||
|
.position-option.active i { |
||||
|
color: #008aff; |
||||
|
} |
||||
|
|
||||
|
.position-option span { |
||||
|
font-size: 13px; |
||||
|
color: #606266; |
||||
|
} |
||||
|
|
||||
|
.dialog-footer { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: flex-end; |
||||
|
padding: 12px 16px; |
||||
|
border-top: 1px solid #e8e8e8; |
||||
|
gap: 8px; |
||||
|
} |
||||
|
</style> |
||||
Loading…
Reference in new issue