增加悬浮窗页面功能

This commit is contained in:
2025-12-29 18:29:33 +08:00
parent bee51d6d1a
commit a9751fa565
10 changed files with 529 additions and 28 deletions

View File

@@ -0,0 +1,178 @@
<template>
<el-dialog :title="form.id ? '编辑' : '添加'" width="400px" v-model="visible" @closed="resetForm">
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px" label-position="left">
<el-form-item label="菜单" prop="menuId">
<el-tree-select
:check-strictly="true"
v-model="form.menuId"
:data="menus"
:render-after-expand="false"
style="width: 240px"
></el-tree-select>
</el-form-item>
<el-form-item label="排序值">
<el-input-number v-model="form.sort" :step="1" step-strictly />
</el-form-item>
<el-form-item label="启用状态">
<el-switch v-model="form.status" :active-value="1" :inactive-value="0"></el-switch>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog_footer">
<div class="btn">
<el-button size="large" style="width: 100%" @click="visible = false"> </el-button>
</div>
<div class="btn">
<el-button
size="large"
type="primary"
:loading="loading"
style="width: 100%"
@click="submitHandle"
>
</el-button>
</div>
</div>
</template>
</el-dialog>
</template>
<script setup>
import { ref, onMounted } from "vue";
import { filterNumberInput } from "@/utils";
import { roleTemplateAdd } from "@/api/account/roleTemplate";
import MenuAPI from "@/api/account/menu";
import quickApi from "@/api/account/quick";
const props = defineProps({
isGetMenu: {
type: Boolean,
required: false,
},
parMenus: {
type: Array,
required: false,
},
item: {
type: Object,
required: false,
},
});
watch(
() => props.item,
(newval) => {
if (newval) {
form.value = newval;
}
},
{ deep: true }
);
const menus = ref([]);
onMounted(async () => {
if (!props.isGetMenu) {
return;
}
const res = await MenuAPI.getRoutes();
console.log("getRoutes", res);
menus.value = returnMenu(res);
console.log(menus.value);
});
watch(
() => props.parMenus.length,
(newval) => {
menus.value = returnMenu(props.parMenus);
}
);
function returnMenu(arr) {
let result = [];
for (let menu of arr) {
menu.label = menu.title;
menu.value = menu.menuId;
result.push({
...menu,
label: menu.title,
value: menu.menuId,
children: menu.children ? returnMenu(menu.children) : [],
});
}
return result;
}
const visible = defineModel({
type: Boolean,
required: false,
});
const formRef = ref(null);
const loading = ref(false);
const form = ref({
menuId: "",
sort: 0,
url: "",
status: 1,
});
const rules = ref({
menuId: [
{
required: true,
message: "请选择菜单",
triiger: "blur",
},
],
});
function resetForm() {
form.value = {
menuId: "",
sort: 0,
url: "",
status: 1,
};
formRef.value.resetFields();
}
// 提交
const emits = defineEmits(["success"]);
function submitHandle() {
formRef.value.validate(async (vaild) => {
try {
if (vaild) {
loading.value = true;
if (form.value.sort === "") {
form.value.sort = 0;
}
await quickApi.add(form.value);
ElNotification({
title: "注意",
message: "添加成功",
type: "success",
});
emits("success");
visible.value = false;
}
} catch (error) {
console.log(error);
}
setTimeout(() => {
loading.value = false;
}, 500);
});
}
</script>
<style scoped lang="scss">
.dialog_footer {
display: flex;
gap: 14px;
.btn {
flex: 1;
}
}
</style>

View File

@@ -0,0 +1,159 @@
<template>
<div class="container">
<div class="table-box">
<div class="row mb-sm">
<el-button type="primary" @click="showAdd = true">添加</el-button>
</div>
<el-table
:data="tableData.list"
v-loading="tableData.loading"
stripe
border
row-key="id"
:tree-props="{ children: 'children' }"
default-expand-all
style="width: 100%"
>
<el-table-column label="ID" prop="id"></el-table-column>
<el-table-column label="菜单名称" prop="isEnable">
<template #default="scope">
{{ returnMenuName(scope.row) }}
</template>
</el-table-column>
<el-table-column label="启用状态" prop="isEnable">
<template #default="scope">
<el-switch
v-model="scope.row.status"
:active-value="1"
:inactive-value="0"
@change="isEnableChange($event, scope.row)"
></el-switch>
</template>
</el-table-column>
<el-table-column label="排序值" prop="sort"></el-table-column>
<el-table-column label="创建时间" prop="createTime"></el-table-column>
<el-table-column label="操作" width="250">
<template #default="scope">
<el-button link type="primary" @click="editMenu(scope.row)">编辑</el-button>
<el-popconfirm title="确认要删除吗?" @confirm="deleteHandle(scope.row)">
<template #reference>
<el-button type="danger" link>删除</el-button>
</template>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
</div>
<dialogAdd
v-model="showAdd"
:parMenus="menus"
@success="Refresh()"
:item="nowEditMenu"
></dialogAdd>
</div>
</template>
<script setup>
import { ref, reactive, onMounted } from "vue";
import MenuAPI from "@/api/account/menu";
import quickApi from "@/api/account/quick";
import dialogAdd from "./dialog-add.vue";
const showAdd = ref(false);
const nowEditMenu = ref({});
function editMenu(item) {
nowEditMenu.value = item;
showAdd.value = true;
}
const tableData = reactive({
loading: false,
page: 1,
size: 10,
total: 0,
list: [],
});
function Refresh() {
getList();
}
function getList() {
tableData.loading = true;
quickApi
.getList({
page: tableData.page,
size: tableData.size,
isEdit: true,
})
.then((res) => {
tableData.list = res;
tableData.total = res.length;
})
.finally(() => {
tableData.loading = false;
});
}
const menus = ref([]);
async function getMenus() {
const res = await MenuAPI.getRoutes();
menus.value = res;
}
const menusIdMap = computed(() => {
const map = getMenuMao();
return map;
});
function returnMenuName(item) {
const menu = menusIdMap.value.get(`${item.menuId}`);
return menu.title;
}
function getMenuMao() {
const map = new Map();
for (const menu of menus.value) {
map.set(menu.menuId, menu);
if (menu.children && menu.children.length > 0) {
for (const child of menu.children) {
map.set(child.menuId, child);
}
}
}
return map;
}
function isEnableChange(value, item) {
quickApi
.edit({
...item,
status: value,
})
.then((res) => {
ElMessage({
message: "修改成功",
type: "success",
});
Refresh();
});
}
function deleteHandle(item) {
quickApi.delete([item.id]).then(() => {
Refresh();
});
}
onMounted(async () => {
await getMenus();
getList();
});
</script>
<style lang="scss" scoped>
.container {
padding: 14px;
width: 100%;
.table-box {
border-radius: 8px;
background-color: #fff;
padding: 14px;
}
}
</style>