Browse Source

操作日志完善(平台)

ctw
cuitw 5 days ago
parent
commit
547688f96f
  1. 25
      ruoyi-ui/src/views/childRoom/LeftMenu.vue
  2. 59
      ruoyi-ui/src/views/childRoom/index.vue
  3. 18
      ruoyi-ui/src/views/dialogs/IconSelectDialog.vue

25
ruoyi-ui/src/views/childRoom/LeftMenu.vue

@ -113,6 +113,11 @@ export default {
type: Array,
default: () => []
},
/** 与 index 中 defaultMenuItems 一致,用于从选择图标中恢复内置项时使用稳定 id */
defaultMenuItems: {
type: Array,
default: () => []
},
position: {
type: String,
default: 'left'
@ -175,18 +180,22 @@ export default {
},
confirmAddIcons(selectedItems) {
const defaults = this.defaultMenuItems || []
selectedItems.forEach(item => {
const newId = Date.now().toString() + Math.random().toString(36).substr(2, 9)
const newMenuItem = {
id: newId,
name: item.name,
icon: item.icon,
action: item.id
const preset = defaults.find(d => d.id === item.id)
if (preset) {
this.localMenuItems.push({ ...preset })
} else {
const newId = Date.now().toString() + Math.random().toString(36).substr(2, 9)
this.localMenuItems.push({
id: newId,
name: item.name,
icon: item.icon,
action: item.id
})
}
this.localMenuItems.push(newMenuItem)
})
this.$emit('update:menuItems', this.localMenuItems)
this.$emit('add-items', selectedItems)
},
quickDelete(item) {

59
ruoyi-ui/src/views/childRoom/index.vue

@ -180,14 +180,14 @@
:menu-items="menuItems"
:active-menu="activeMenu"
:is-edit-mode="isIconEditMode"
:available-icons="topNavItems"
:available-icons="iconPickerCatalog"
:default-menu-items="defaultMenuItems"
:position="menuPosition"
@hide="hideMenu"
@select="selectMenu"
@menu-action="handleMenuAction"
@update:menu-items="updateMenuItems"
@drag-end="handleMenuDragEnd"
@add-items="handleAddMenuItems"
@delete="handleDeleteMenuItem"
@save-menu-items="handleSaveMenuItems"
@exit-icon-edit="exitIconEdit"
@ -1071,6 +1071,13 @@ export default {
if (editor && Number(editor.userId) !== Number(myId)) ids.push(Number(rid));
});
return ids;
},
/** 左侧「选择图标」:全部默认菜单样式 + 不与默认 id 重复的扩展项 */
iconPickerCatalog() {
const defs = this.defaultMenuItems || [];
const seen = new Set(defs.map(d => d.id));
const extras = (this.topNavItems || []).filter(t => !seen.has(t.id));
return [...defs, ...extras];
}
},
mounted() {
@ -3789,19 +3796,6 @@ export default {
this.menuItems = newItems
},
handleAddMenuItems(selectedItems) {
selectedItems.forEach(item => {
const newId = Date.now().toString() + Math.random().toString(36).substr(2, 9)
const newMenuItem = {
id: newId,
name: item.name,
icon: item.icon,
action: item.id
}
this.menuItems.push(newMenuItem)
})
},
handleMenuAction(actionId) {
const actionMap = {
'savePlan': () => this.savePlan(),
@ -4495,43 +4489,32 @@ export default {
}
},
/** 加载当前用户的左侧菜单配置(登录且有过保存时生效) */
/** 加载当前用户的左侧菜单配置(以数据库为准,不自动补回已删除的默认项) */
async loadUserMenuConfig() {
try {
const res = await getMenuConfig()
const data = res && res.data
if (!data) return
if (data.menuItems) {
if (data.menuItems != null && data.menuItems !== '') {
let arr = []
try {
arr = typeof data.menuItems === 'string' ? JSON.parse(data.menuItems) : data.menuItems
} catch (e) { /* 解析失败保留默认 */ }
if (Array.isArray(arr) && arr.length > 0) {
const defaultMap = (this.defaultMenuItems || []).reduce((m, it) => { m[it.id] = it; return m }, {})
const savedIds = new Set(arr.map(i => i.id))
// 4T defaultMenuItems
const defaultOrder = (this.defaultMenuItems || []).map(d => d.id)
defaultOrder.forEach(defId => {
if (!savedIds.has(defId) && defaultMap[defId]) {
const insertAfterId = defaultOrder[defaultOrder.indexOf(defId) - 1]
const refIdx = insertAfterId ? arr.findIndex(i => i.id === insertAfterId) : -1
const insertIdx = refIdx >= 0 ? refIdx + 1 : 0
arr.splice(insertIdx, 0, { ...defaultMap[defId] })
savedIds.add(defId)
}
})
this.menuItems = arr.map(item => {
const def = defaultMap[item.id]
if (def) return { ...item, name: def.name, icon: def.icon, action: def.action }
return item
})
} catch (e) {
return
}
if (!Array.isArray(arr)) return
const defaultMap = (this.defaultMenuItems || []).reduce((m, it) => { m[it.id] = it; return m }, {})
this.menuItems = arr.map(item => {
const def = defaultMap[item.id]
if (def) return { ...item, name: def.name, icon: def.icon, action: def.action }
return item
})
}
if (data.position && ['left', 'top', 'bottom'].includes(data.position)) {
this.menuPosition = data.position
}
} catch (e) {
// 使
// 使 mounted
}
},

18
ruoyi-ui/src/views/dialogs/IconSelectDialog.vue

@ -16,7 +16,8 @@
:class="{ selected: selectedIcons.includes(item.id) }"
@click="toggleIcon(item)"
>
<i :class="item.icon"></i>
<svg-icon v-if="isSvgIcon(item.icon)" :icon-class="item.icon" class="icon-select-svg" />
<i v-else :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>
@ -72,6 +73,9 @@ export default {
}
},
methods: {
isSvgIcon(icon) {
return icon && typeof icon === 'string' && !icon.startsWith('el-icon-')
},
toggleIcon(item) {
const index = this.selectedIcons.indexOf(item.id)
if (index > -1) {
@ -143,15 +147,23 @@ export default {
background: rgba(22, 93, 255, 0.1);
}
.icon-item i {
.icon-item i,
.icon-item .icon-select-svg {
font-size: 28px;
color: #555;
margin-bottom: 8px;
transition: color 0.3s;
}
.icon-item .icon-select-svg {
width: 28px;
height: 28px;
}
.icon-item:hover i,
.icon-item.selected i {
.icon-item:hover .icon-select-svg,
.icon-item.selected i,
.icon-item.selected .icon-select-svg {
color: #165dff;
}

Loading…
Cancel
Save