refactor: keepalive无效问题修复和代码vue社区代码规范调整
Former-commit-id: f661982d54f1738ff9739f1afc993181a466f052
This commit is contained in:
@@ -1,3 +1,174 @@
|
||||
<!-- setup 无法设置组件名称,组件名称keepAlive必须 -->
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: "client"
|
||||
};
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
listClientPages,
|
||||
getClientFormDetial,
|
||||
addClient,
|
||||
updateClient,
|
||||
deleteClients,
|
||||
} from "@/api/system/client";
|
||||
import { Search, Plus, Edit, Refresh, Delete } from "@element-plus/icons-vue";
|
||||
import { onMounted, reactive, getCurrentInstance, ref, toRefs } from "vue";
|
||||
import { ElForm, ElMessage, ElMessageBox } from "element-plus";
|
||||
import { ClientFormData, ClientItem, ClientQueryParam, Option } from "@/types";
|
||||
const { proxy }: any = getCurrentInstance();
|
||||
|
||||
const queryFormRef = ref(ElForm);
|
||||
const dataFormRef = ref(ElForm);
|
||||
const state = reactive({
|
||||
loading: true,
|
||||
// 选中ID数组
|
||||
ids: [],
|
||||
// 非单个禁用
|
||||
single: true,
|
||||
// 非多个禁用
|
||||
multiple: true,
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
} as ClientQueryParam,
|
||||
clientList: [] as ClientItem[],
|
||||
total: 0,
|
||||
dialog: {
|
||||
title: "",
|
||||
visible: false,
|
||||
type: "create",
|
||||
},
|
||||
formData: {} as ClientFormData,
|
||||
rules: {
|
||||
clientId: [
|
||||
{ required: true, message: "客户端ID不能为空", trigger: "blur" },
|
||||
],
|
||||
},
|
||||
authorizedGrantTypesOptions: [] as Option[],
|
||||
checkedAuthorizedGrantTypes: [] as string[]
|
||||
});
|
||||
|
||||
const {
|
||||
loading,
|
||||
ids,
|
||||
multiple,
|
||||
queryParams,
|
||||
clientList,
|
||||
total,
|
||||
dialog,
|
||||
formData,
|
||||
rules,
|
||||
authorizedGrantTypesOptions,
|
||||
checkedAuthorizedGrantTypes,
|
||||
} = toRefs(state);
|
||||
|
||||
function handleQuery() {
|
||||
listClientPages(state.queryParams).then(({ data }) => {
|
||||
state.clientList = data.list;
|
||||
state.total = data.total;
|
||||
state.loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
function resetQuery() {
|
||||
queryFormRef.value.resetFields();
|
||||
handleQuery();
|
||||
}
|
||||
|
||||
function handleSelectionChange(selection: any) {
|
||||
state.ids = selection.map((item: any) => item.clientId);
|
||||
state.single = selection.length !== 1;
|
||||
state.multiple = !selection.length;
|
||||
}
|
||||
|
||||
function handleAdd() {
|
||||
proxy.$listDictsByCode("grant_type").then((response: any) => {
|
||||
state.authorizedGrantTypesOptions = response.data;
|
||||
});
|
||||
|
||||
state.dialog = {
|
||||
title: "添加客户端",
|
||||
visible: true,
|
||||
type: "create",
|
||||
};
|
||||
}
|
||||
|
||||
function handleUpdate(row: any) {
|
||||
state.dialog = {
|
||||
title: "修改客户端",
|
||||
visible: true,
|
||||
type: "edit",
|
||||
};
|
||||
const clientId = row.clientId || ids;
|
||||
|
||||
proxy.$listDictsByCode("grant_type").then((res: any) => {
|
||||
state.authorizedGrantTypesOptions = res.data;
|
||||
|
||||
getClientFormDetial(clientId).then(({ data }) => {
|
||||
state.formData = data;
|
||||
state.checkedAuthorizedGrantTypes = data.authorizedGrantTypes?.split(",");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function submitForm() {
|
||||
dataFormRef.value.validate((isvalid: boolean) => {
|
||||
if (isvalid) {
|
||||
state.formData.authorizedGrantTypes =
|
||||
state.checkedAuthorizedGrantTypes.join(",");
|
||||
if (state.dialog.type == "edit") {
|
||||
updateClient(state.formData.clientId, state.formData).then(
|
||||
() => {
|
||||
ElMessage.success("修改成功");
|
||||
state.dialog.visible = false;
|
||||
cancel();
|
||||
handleQuery();
|
||||
}
|
||||
);
|
||||
} else {
|
||||
addClient(state.formData).then(() => {
|
||||
ElMessage.success("新增成功");
|
||||
cancel();
|
||||
handleQuery();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function resetForm() {
|
||||
dataFormRef.value.resetFields();
|
||||
state.checkedAuthorizedGrantTypes = [];
|
||||
}
|
||||
|
||||
function cancel() {
|
||||
resetForm();
|
||||
state.dialog.visible = false;
|
||||
}
|
||||
|
||||
function handleDelete(row: any) {
|
||||
const clientIds = [row.clientId || ids].join(",");
|
||||
ElMessageBox.confirm("确认删除已选中的数据项?", "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(() => {
|
||||
deleteClients(clientIds).then(() => {
|
||||
ElMessage.success("删除成功");
|
||||
handleQuery();
|
||||
});
|
||||
})
|
||||
.catch(() => ElMessage.info("已取消删除"));
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
handleQuery();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!-- 搜索表单 -->
|
||||
@@ -126,168 +297,4 @@
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
listClientPages,
|
||||
getClientFormDetial,
|
||||
addClient,
|
||||
updateClient,
|
||||
deleteClients,
|
||||
} from "@/api/system/client";
|
||||
import { Search, Plus, Edit, Refresh, Delete } from "@element-plus/icons-vue";
|
||||
import { onMounted, reactive, getCurrentInstance, ref, toRefs } from "vue";
|
||||
import { ElForm, ElMessage, ElMessageBox } from "element-plus";
|
||||
import { ClientFormData, ClientItem, ClientQueryParam, Option } from "@/types";
|
||||
const { proxy }: any = getCurrentInstance();
|
||||
|
||||
const queryFormRef = ref(ElForm);
|
||||
const dataFormRef = ref(ElForm);
|
||||
const state = reactive({
|
||||
loading: true,
|
||||
// 选中ID数组
|
||||
ids: [],
|
||||
// 非单个禁用
|
||||
single: true,
|
||||
// 非多个禁用
|
||||
multiple: true,
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
} as ClientQueryParam,
|
||||
clientList: [] as ClientItem[],
|
||||
total: 0,
|
||||
dialog: {
|
||||
title: "",
|
||||
visible: false,
|
||||
type: "create",
|
||||
},
|
||||
formData: {} as ClientFormData,
|
||||
rules: {
|
||||
clientId: [
|
||||
{ required: true, message: "客户端ID不能为空", trigger: "blur" },
|
||||
],
|
||||
},
|
||||
authorizedGrantTypesOptions: [] as Option[],
|
||||
checkedAuthorizedGrantTypes: [] as string[],
|
||||
});
|
||||
|
||||
const {
|
||||
loading,
|
||||
ids,
|
||||
multiple,
|
||||
queryParams,
|
||||
clientList,
|
||||
total,
|
||||
dialog,
|
||||
formData,
|
||||
rules,
|
||||
authorizedGrantTypesOptions,
|
||||
checkedAuthorizedGrantTypes,
|
||||
} = toRefs(state);
|
||||
|
||||
function handleQuery() {
|
||||
listClientPages(state.queryParams).then(({ data }) => {
|
||||
state.clientList = data.list;
|
||||
state.total = data.total;
|
||||
state.loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
function resetQuery() {
|
||||
queryFormRef.value.resetFields();
|
||||
handleQuery();
|
||||
}
|
||||
|
||||
function handleSelectionChange(selection: any) {
|
||||
state.ids = selection.map((item: any) => item.clientId);
|
||||
state.single = selection.length !== 1;
|
||||
state.multiple = !selection.length;
|
||||
}
|
||||
|
||||
function handleAdd() {
|
||||
proxy.$listDictsByCode("grant_type").then((response: any) => {
|
||||
state.authorizedGrantTypesOptions = response.data;
|
||||
});
|
||||
|
||||
state.dialog = {
|
||||
title: "添加客户端",
|
||||
visible: true,
|
||||
type: "create",
|
||||
};
|
||||
}
|
||||
|
||||
function handleUpdate(row: any) {
|
||||
state.dialog = {
|
||||
title: "修改客户端",
|
||||
visible: true,
|
||||
type: "edit",
|
||||
};
|
||||
const clientId = row.clientId || ids;
|
||||
|
||||
proxy.$listDictsByCode("grant_type").then((res: any) => {
|
||||
state.authorizedGrantTypesOptions = res.data;
|
||||
|
||||
getClientFormDetial(clientId).then(({ data }) => {
|
||||
state.formData = data;
|
||||
state.checkedAuthorizedGrantTypes = data.authorizedGrantTypes?.split(",");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function submitForm() {
|
||||
dataFormRef.value.validate((isvalid: boolean) => {
|
||||
if (isvalid) {
|
||||
state.formData.authorizedGrantTypes =
|
||||
state.checkedAuthorizedGrantTypes.join(",");
|
||||
if (state.dialog.type == "edit") {
|
||||
updateClient(state.formData.clientId, state.formData).then(
|
||||
() => {
|
||||
ElMessage.success("修改成功");
|
||||
state.dialog.visible = false;
|
||||
cancel();
|
||||
handleQuery();
|
||||
}
|
||||
);
|
||||
} else {
|
||||
addClient(state.formData).then(() => {
|
||||
ElMessage.success("新增成功");
|
||||
cancel();
|
||||
handleQuery();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function resetForm() {
|
||||
dataFormRef.value.resetFields();
|
||||
state.checkedAuthorizedGrantTypes = [];
|
||||
}
|
||||
|
||||
function cancel() {
|
||||
resetForm();
|
||||
state.dialog.visible = false;
|
||||
}
|
||||
|
||||
function handleDelete(row: any) {
|
||||
const clientIds = [row.clientId || ids].join(",");
|
||||
ElMessageBox.confirm("确认删除已选中的数据项?", "警告", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(() => {
|
||||
deleteClients(clientIds).then(() => {
|
||||
ElMessage.success("删除成功");
|
||||
handleQuery();
|
||||
});
|
||||
})
|
||||
.catch(() => ElMessage.info("已取消删除"));
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
handleQuery();
|
||||
});
|
||||
</script>
|
||||
</template>
|
||||
@@ -1,85 +1,9 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form-item>
|
||||
<el-button type="success" :icon="Plus" @click="handleAdd">新增</el-button>
|
||||
<el-button type="danger" :icon="Delete" :disabled="single" @click="handleDelete">删除
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="name">
|
||||
<el-input v-model="queryParams.name" placeholder="请输入部门名称" @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="status">
|
||||
<el-select v-model="queryParams.status" placeholder="部门状态" clearable>
|
||||
<el-option :value="1" label="正常" />
|
||||
<el-option :value="0" label="禁用" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button class="filter-item" type="primary" :icon="Search" @click="handleQuery">
|
||||
搜索
|
||||
</el-button>
|
||||
<el-button :icon="Refresh" @click="resetQuery"> 重置 </el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-table v-loading="loading" :data="deptList" row-key="id" default-expand-all
|
||||
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column prop="name" label="部门名称" />
|
||||
<el-table-column prop="status" label="状态" width="100">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.status == 1" type="success">正常</el-tag>
|
||||
<el-tag v-else type="info">禁用</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="sort" label="显示排序" width="200" />
|
||||
|
||||
<el-table-column label="操作" align="center" width="150">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" :icon="Edit" circle plain @click.stop="handleUpdate(scope.row)">
|
||||
</el-button>
|
||||
<el-button type="success" :icon="Plus" circle plain @click.stop="handleAdd(scope.row)">
|
||||
</el-button>
|
||||
|
||||
<el-button type="danger" :icon="Delete" circle plain @click.stop="handleDelete(scope.row)">
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 添加或修改部门对话框 -->
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="600px" @closed="cancel">
|
||||
<el-form ref="dataFormRef" :model="formData" :rules="rules" label-width="80px">
|
||||
<el-form-item label="上级部门" prop="parentId">
|
||||
<el-tree-select v-model="formData.parentId" placeholder="选择上级部门" :data="deptOptions" filterable check-strictly />
|
||||
</el-form-item>
|
||||
<el-form-item label="部门名称" prop="name">
|
||||
<el-input v-model="formData.name" placeholder="请输入部门名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="显示排序" prop="sort">
|
||||
<el-input-number v-model="formData.sort" controls-position="right" style="width: 100px" :min="0" />
|
||||
</el-form-item>
|
||||
<el-form-item label="部门状态">
|
||||
<el-radio-group v-model="formData.status">
|
||||
<el-radio :label="1">正常</el-radio>
|
||||
<el-radio :label="0">禁用</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm"> 确 定 </el-button>
|
||||
<el-button @click="cancel"> 取 消 </el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<!-- setup 无法设置组件名称,组件名称keepAlive必须 -->
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: "dept"
|
||||
};
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
// Vue依赖
|
||||
@@ -92,7 +16,7 @@ import {
|
||||
updateDept,
|
||||
addDept,
|
||||
listSelectDepartments,
|
||||
listTableDepartments,
|
||||
listTableDepartments
|
||||
} from "@/api/system/dept";
|
||||
|
||||
// 组件依赖
|
||||
@@ -195,7 +119,7 @@ async function loadDeptData() {
|
||||
*/
|
||||
function handleAdd(row: any) {
|
||||
loadDeptData();
|
||||
state.formData.id=undefined
|
||||
state.formData.id = undefined
|
||||
state.formData.parentId = row.id;
|
||||
state.dialog = {
|
||||
title: "添加部门",
|
||||
@@ -278,3 +202,85 @@ onMounted(() => {
|
||||
handleQuery();
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form-item>
|
||||
<el-button type="success" :icon="Plus" @click="handleAdd">新增</el-button>
|
||||
<el-button type="danger" :icon="Delete" :disabled="single" @click="handleDelete">删除
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="name">
|
||||
<el-input v-model="queryParams.name" placeholder="请输入部门名称" @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="status">
|
||||
<el-select v-model="queryParams.status" placeholder="部门状态" clearable>
|
||||
<el-option :value="1" label="正常" />
|
||||
<el-option :value="0" label="禁用" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button class="filter-item" type="primary" :icon="Search" @click="handleQuery">
|
||||
搜索
|
||||
</el-button>
|
||||
<el-button :icon="Refresh" @click="resetQuery"> 重置 </el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-table v-loading="loading" :data="deptList" row-key="id" default-expand-all
|
||||
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column prop="name" label="部门名称" />
|
||||
<el-table-column prop="status" label="状态" width="100">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.status == 1" type="success">正常</el-tag>
|
||||
<el-tag v-else type="info">禁用</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="sort" label="显示排序" width="200" />
|
||||
|
||||
<el-table-column label="操作" align="center" width="150">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" :icon="Edit" circle plain @click.stop="handleUpdate(scope.row)">
|
||||
</el-button>
|
||||
<el-button type="success" :icon="Plus" circle plain @click.stop="handleAdd(scope.row)">
|
||||
</el-button>
|
||||
|
||||
<el-button type="danger" :icon="Delete" circle plain @click.stop="handleDelete(scope.row)">
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 添加或修改部门对话框 -->
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="600px" @closed="cancel">
|
||||
<el-form ref="dataFormRef" :model="formData" :rules="rules" label-width="80px">
|
||||
<el-form-item label="上级部门" prop="parentId">
|
||||
<el-tree-select v-model="formData.parentId" placeholder="选择上级部门" :data="deptOptions" filterable check-strictly />
|
||||
</el-form-item>
|
||||
<el-form-item label="部门名称" prop="name">
|
||||
<el-input v-model="formData.name" placeholder="请输入部门名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="显示排序" prop="sort">
|
||||
<el-input-number v-model="formData.sort" controls-position="right" style="width: 100px" :min="0" />
|
||||
</el-form-item>
|
||||
<el-form-item label="部门状态">
|
||||
<el-radio-group v-model="formData.status">
|
||||
<el-radio :label="1">正常</el-radio>
|
||||
<el-radio :label="0">禁用</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm"> 确 定 </el-button>
|
||||
<el-button @click="cancel"> 取 消 </el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
<!-- setup 无法设置组件名称,组件名称keepAlive必须 -->
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: "dict"
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!-- 搜索表单 -->
|
||||
|
||||
@@ -57,26 +57,30 @@
|
||||
<el-input v-model="formData.name" placeholder="请输入菜单名称" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="是否外链">
|
||||
<el-radio-group v-model="isExternalPath">
|
||||
<el-radio :label="false">否</el-radio>
|
||||
<el-radio :label="true">是</el-radio>
|
||||
<el-form-item label="菜单类型">
|
||||
<el-radio-group v-model="formData.type" @change="handleMenuTypeChange">
|
||||
<el-radio label="MENU">菜单</el-radio>
|
||||
<el-radio label="CATALOG">目录</el-radio>
|
||||
<el-radio label="EXTLINK">外链</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-if="isExternalPath" label="外链地址" prop="path">
|
||||
<!-- 路由路径(浏览器地址栏显示) -->
|
||||
<el-form-item v-if="formData.type == 'EXTLINK'" label="外链地址" prop="path">
|
||||
<el-input v-model="formData.path" placeholder="请输入外链完整路径" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-if="!isExternalPath" label="页面路径" prop="component">
|
||||
<el-form-item v-else label="路由路径" prop="path">
|
||||
<el-input v-if="formData.type == 'CATALOG'" v-model="formData.path" placeholder="/system (注意:目录以/开头)" />
|
||||
<el-input v-else v-model="formData.path" placeholder="user" />
|
||||
</el-form-item>
|
||||
|
||||
<!-- 组件页面完整路径 -->
|
||||
<el-form-item v-if="formData.type == 'MENU'" label="组件路径" prop="component">
|
||||
<el-input v-model="formData.component" placeholder="system/user/index" style="width: 95%">
|
||||
<template v-if="formData.parentId != '0'" #prepend>src/views/</template>
|
||||
<template v-if="formData.parentId != '0'" #append>.vue</template>
|
||||
</el-input>
|
||||
|
||||
<el-tooltip effect="dark" content="请输入组件路径,如果是父组件填写 Layout 即可" placement="right">
|
||||
<i class="el-icon-info" style="margin-left: 10px; color: darkseagreen"></i>
|
||||
</el-tooltip>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="图标" prop="icon">
|
||||
@@ -93,6 +97,10 @@
|
||||
</el-popover>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="跳转路由">
|
||||
<el-input v-model="formData.redirect" placeholder="跳转路由路径" maxlength="50" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="状态">
|
||||
<el-radio-group v-model="formData.visible">
|
||||
<el-radio :label="1">显示</el-radio>
|
||||
@@ -104,9 +112,7 @@
|
||||
<el-input-number v-model="formData.sort" style="width: 100px" controls-position="right" :min="0" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="跳转路径">
|
||||
<el-input v-model="formData.redirect" placeholder="请输入跳转路径" maxlength="50" />
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
@@ -125,7 +131,6 @@ import { reactive, ref, onMounted, toRefs } from "vue";
|
||||
import { Search, Plus, Edit, Refresh, Delete } from "@element-plus/icons-vue";
|
||||
import { ElForm, ElMessage, ElMessageBox, ElPopover } from "element-plus";
|
||||
|
||||
import { isExternal } from "@/utils/validate";
|
||||
import {
|
||||
Dialog,
|
||||
Option,
|
||||
@@ -164,20 +169,28 @@ const state = reactive({
|
||||
dialog: { visible: false } as Dialog,
|
||||
formData: {
|
||||
parentId: "0",
|
||||
name: '',
|
||||
visible: 1,
|
||||
sort: 1,
|
||||
component: "Layout",
|
||||
component: 'Layout',
|
||||
type: 'MENU'
|
||||
} as MenuFormData,
|
||||
rules: {
|
||||
parentId: [{ required: true, message: "请选择顶级菜单", trigger: "blur" }],
|
||||
name: [{ required: true, message: "请输入菜单名称", trigger: "blur" }],
|
||||
component: [{ required: true, message: "请输入页面路径", trigger: "blur" }],
|
||||
type: [{ required: true, message: "请选择菜单类型", trigger: "blur" }],
|
||||
path: [{ required: true, message: "请输入路由路径", trigger: "blur" }],
|
||||
component: [{ required: true, message: "请输入组件完整路径", trigger: "blur" }]
|
||||
},
|
||||
menuOptions: [] as Option[],
|
||||
currentRow: undefined,
|
||||
isExternalPath: false,
|
||||
// Icon选择器显示状态
|
||||
iconSelectVisible: false
|
||||
iconSelectVisible: false,
|
||||
cacheData: {
|
||||
menuType: '',
|
||||
menuPath: ''
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
const {
|
||||
@@ -188,8 +201,8 @@ const {
|
||||
formData,
|
||||
rules,
|
||||
menuOptions,
|
||||
isExternalPath,
|
||||
iconSelectVisible
|
||||
iconSelectVisible,
|
||||
cacheData
|
||||
} = toRefs(state);
|
||||
|
||||
/**
|
||||
@@ -237,26 +250,29 @@ async function handleAdd(row: any) {
|
||||
title: "添加菜单",
|
||||
visible: true
|
||||
};
|
||||
if (row.id) {
|
||||
// 行点击新增
|
||||
if (row.id) { // 行点击新增
|
||||
|
||||
state.formData.parentId = row.id;
|
||||
if (row.id == '0') {
|
||||
state.formData.component = "Layout";
|
||||
state.formData.type = 'CATALOG';
|
||||
} else {
|
||||
state.formData.component = undefined;
|
||||
state.formData.type = 'MENU';
|
||||
}
|
||||
} else {
|
||||
} else { // 工具栏新增
|
||||
if (state.currentRow) {
|
||||
// 工具栏新增
|
||||
state.formData.parentId = (state.currentRow as any).id;
|
||||
state.formData.component = undefined;
|
||||
state.formData.type = 'MENU';
|
||||
} else {
|
||||
state.formData.parentId = "0";
|
||||
state.formData.component = "Layout";
|
||||
state.formData.type = 'CATALOG';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 修改弹窗
|
||||
*/
|
||||
async function handleUpdate(row: any) {
|
||||
await loadMenuData();
|
||||
state.dialog = {
|
||||
@@ -266,13 +282,25 @@ async function handleUpdate(row: any) {
|
||||
const id = row.id || state.ids;
|
||||
getMenuDetail(id).then(({ data }) => {
|
||||
state.formData = data;
|
||||
// 判断是否外部链接
|
||||
state.isExternalPath = isExternal(state.formData.path);
|
||||
cacheData.value.menuType = data.type
|
||||
cacheData.value.menuPath = data.path
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 菜单表单提交
|
||||
* 菜单类型change事件
|
||||
*/
|
||||
function handleMenuTypeChange(val: any) {
|
||||
if (val !== cacheData.value.menuType) {
|
||||
formData.value.path = ''
|
||||
} else {
|
||||
formData.value.path = cacheData.value.menuPath
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 菜单提交
|
||||
*/
|
||||
function submitForm() {
|
||||
dataFormRef.value.validate((isValid: boolean) => {
|
||||
@@ -326,7 +354,6 @@ function selected(name: string) {
|
||||
state.iconSelectVisible = false;
|
||||
}
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
handleQuery();
|
||||
});
|
||||
|
||||
@@ -1,33 +1,23 @@
|
||||
<template>
|
||||
<div class="menu-container">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-button plain :icon="Switch" @click="toggleExpandAll">展开/折叠</el-button>
|
||||
</el-col>
|
||||
<el-col :span="12" style="text-align: right">
|
||||
<el-button type="primary" :icon="Check" @click="handleSubmit">提交</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-tree class="menu-container__tree" ref="menuRef" v-if="refreshTree" :default-expanded-keys="expandedKeys" :default-expand-all="isExpandAll"
|
||||
:data="menuOptions" show-checkbox node-key="value" empty-text="加载菜单中..." :check-strictly="checkStrictly"
|
||||
highlight-current @node-click="handleNodeClick" />
|
||||
</div>
|
||||
</template>
|
||||
<!-- setup 无法设置组件名称,组件名称keepAlive必须 -->
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: "cmenu"
|
||||
};
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { nextTick, onMounted, reactive, ref, toRefs, watch } from "vue";
|
||||
import { listSelectMenus } from "@/api/system/menu";
|
||||
import { listRoleMenuIds, updateRoleMenu } from "@/api/system/role";
|
||||
import { ElTree, ElMessage } from "element-plus";
|
||||
import { Switch, Check } from "@element-plus/icons-vue";
|
||||
import { Switch, Position } from "@element-plus/icons-vue";
|
||||
import { Option } from "@/types";
|
||||
|
||||
const emit = defineEmits(["menuClick"]);
|
||||
const props = defineProps({
|
||||
role: {
|
||||
type: Object,
|
||||
default: () => { }
|
||||
default: () => {}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -99,10 +89,25 @@ onMounted(() => {
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-button plain :icon="Switch" @click="toggleExpandAll">展开/折叠</el-button>
|
||||
</el-col>
|
||||
<el-col :span="12" style="text-align: right">
|
||||
<el-button type="primary" :icon="Position" @click="handleSubmit">提交</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-tree class="menu-tree" ref="menuRef" v-if="refreshTree" :default-expanded-keys="expandedKeys"
|
||||
:default-expand-all="isExpandAll" :data="menuOptions" show-checkbox node-key="value" empty-text="加载菜单中..."
|
||||
:check-strictly="checkStrictly" highlight-current @node-click="handleNodeClick" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.menu-container {
|
||||
&__tree{
|
||||
margin-top: 10px;
|
||||
}
|
||||
.menu-tree {
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
</el-checkbox>
|
||||
</el-col>
|
||||
<el-col :span="12" style="text-align: right">
|
||||
<el-button type="primary" :icon="Check" @click="handleSubmit">提交</el-button>
|
||||
<el-button type="primary" :icon="Position" @click="handleSubmit">提交</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
@@ -36,7 +36,7 @@ import { onMounted, reactive, toRefs, watch } from "vue";
|
||||
import { listPerms } from "@/api/system/perm";
|
||||
import { listRolePerms, saveRolePerms } from "@/api/system/role";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { Check } from "@element-plus/icons-vue";
|
||||
import { Position } from "@element-plus/icons-vue";
|
||||
import { PermQueryParam } from "@/types";
|
||||
|
||||
const props = defineProps({
|
||||
|
||||
@@ -1,72 +1,9 @@
|
||||
<template>
|
||||
<div class="role-container">
|
||||
<!-- 搜索表单 -->
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form-item>
|
||||
<el-button type="success" :icon="Plus" @click="handleAdd">新增</el-button>
|
||||
<el-button type="danger" :icon="Delete" :disabled="multiple" @click="handleDelete">删除</el-button>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="name">
|
||||
<el-input v-model="queryParams.name" placeholder="角色名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button :icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<el-table ref="dataTableRef" v-loading="loading" :data="roleList" @selection-change="handleSelectionChange"
|
||||
@row-click="handleRowClick" highlight-current-row border>
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="角色名称" prop="name" />
|
||||
<el-table-column label="角色编码" prop="code" />
|
||||
<el-table-column label="操作" align="center" width="120">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" :icon="Edit" circle plain @click.stop="handleUpdate(scope.row)" />
|
||||
<el-button type="danger" :icon="Delete" circle plain @click.stop="handleDelete(scope.row)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页工具条 -->
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
|
||||
@pagination="handleQuery" />
|
||||
|
||||
<!-- 表单弹窗 -->
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" @close="cancel" width="450px">
|
||||
<el-form ref="dataFormRef" :model="formData" :rules="rules" label-width="100px">
|
||||
<el-form-item label="角色名称" prop="name">
|
||||
<el-input v-model="formData.name" placeholder="请输入角色名称" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="角色编码" prop="code">
|
||||
<el-input v-model="formData.code" placeholder="请输入角色编码" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number v-model="formData.sort" controls-position="right" :min="0" style="width: 100px" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="状态">
|
||||
<el-radio-group v-model="formData.status">
|
||||
<el-radio :label="1">正常</el-radio>
|
||||
<el-radio :label="0">停用</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<!-- setup 无法设置组件名称,组件名称keepAlive必须 -->
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: "role"
|
||||
};
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, reactive, ref, toRefs } from "vue";
|
||||
@@ -107,7 +44,7 @@ const state = reactive({
|
||||
rules: {
|
||||
name: [{ required: true, message: "请输入角色名称", trigger: "blur" }],
|
||||
code: [{ required: true, message: "请输入角色编码", trigger: "blur" }],
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
const {
|
||||
@@ -215,8 +152,77 @@ onMounted(() => {
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!-- 搜索表单 -->
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form-item>
|
||||
<el-button type="success" :icon="Plus" @click="handleAdd">新增</el-button>
|
||||
<el-button type="danger" :icon="Delete" :disabled="multiple" @click="handleDelete">删除</el-button>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="name">
|
||||
<el-input v-model="queryParams.name" placeholder="角色名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button :icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<el-table ref="dataTableRef" v-loading="loading" :data="roleList" @selection-change="handleSelectionChange"
|
||||
@row-click="handleRowClick" highlight-current-row border>
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="角色名称" prop="name" />
|
||||
<el-table-column label="角色编码" prop="code" />
|
||||
<el-table-column label="操作" align="center" width="120">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" :icon="Edit" circle plain @click.stop="handleUpdate(scope.row)" />
|
||||
<el-button type="danger" :icon="Delete" circle plain @click.stop="handleDelete(scope.row)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页工具条 -->
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize" @pagination="handleQuery" />
|
||||
|
||||
<!-- 表单弹窗 -->
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" @close="cancel" width="450px">
|
||||
<el-form ref="dataFormRef" :model="formData" :rules="rules" label-width="100px">
|
||||
<el-form-item label="角色名称" prop="name">
|
||||
<el-input v-model="formData.name" placeholder="请输入角色名称" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="角色编码" prop="code">
|
||||
<el-input v-model="formData.code" placeholder="请输入角色编码" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number v-model="formData.sort" controls-position="right" :min="0" style="width: 100px" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="状态">
|
||||
<el-radio-group v-model="formData.status">
|
||||
<el-radio :label="1">正常</el-radio>
|
||||
<el-radio :label="0">停用</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.role-container {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -1,189 +1,9 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-row :gutter="20">
|
||||
<!-- 部门树 -->
|
||||
<el-col :span="4" :xs="24">
|
||||
<el-card class="box-card">
|
||||
<el-input v-model="deptName" placeholder="部门名称" clearable :prefix-icon="Search" style="margin-bottom: 20px" />
|
||||
<el-tree ref="deptTreeRef" :data="deptOptions" :props="{ children: 'children', label: 'label', disabled: '' }"
|
||||
:expand-on-click-node="false" :filter-node-method="filterDeptNode" default-expand-all
|
||||
@node-click="handleDeptNodeClick"></el-tree>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
||||
<!-- 用户数据 -->
|
||||
<el-col :span="20" :xs="24">
|
||||
<el-card class="box-card">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-row>
|
||||
<el-col :span="18" :xs="24" >
|
||||
<el-form-item>
|
||||
<el-button type="success" :icon="Plus" @click="handleAdd" v-hasPerm="['sys:user:add']">新增</el-button>
|
||||
<el-button type="danger" :icon="Delete" :disabled="multiple" @click="handleDelete"
|
||||
v-hasPerm="['sys:user:delete']">删除</el-button>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="keywords">
|
||||
<el-input v-model="queryParams.keywords" placeholder="用户名/昵称/手机号" clearable style="width: 200px"
|
||||
@keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="status">
|
||||
<el-select v-model="queryParams.status" placeholder="用户状态" clearable style="width: 200px">
|
||||
<el-option label="正常" value="1" />
|
||||
<el-option label="停用" value="0" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button :icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="6" :xs="24" style="text-align: right;">
|
||||
<el-form-item>
|
||||
<el-dropdown split-button style="margin-left: 12px;">
|
||||
导入
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item :icon="Download" @click="handleDownloadTemplate">下载模板</el-dropdown-item>
|
||||
<el-dropdown-item :icon="Top" @click="showImportDialog">导入数据</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
<el-button :icon="Download" style="margin-left: 12px;" @click="handleExport">导出</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
|
||||
<el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="50" align="center" />
|
||||
<el-table-column key="id" label="用户编号" align="center" prop="id" />
|
||||
<el-table-column key="username" label="用户名" align="center" prop="username" />
|
||||
<el-table-column label="用户昵称" align="center" prop="nickname" />
|
||||
|
||||
<el-table-column label="性别" align="center" prop="gender" />
|
||||
|
||||
<el-table-column label="部门" align="center" prop="deptName" />
|
||||
<el-table-column label="手机号码" align="center" prop="mobile" width="120" />
|
||||
|
||||
<el-table-column label="状态" align="center" prop="status">
|
||||
<template #default="scope">
|
||||
<el-switch v-model="scope.row.status" :inactive-value="0" :active-value="1"
|
||||
@change="handleStatusChange(scope.row)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="gmtCreate" width="180"></el-table-column>
|
||||
<el-table-column label="操作" align="center" width="150">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" :icon="Edit" circle plain @click="handleUpdate(scope.row)"
|
||||
v-hasPerm="['sys:user:edit']"></el-button>
|
||||
<el-button type="danger" :icon="Delete" circle plain @click="handleDelete(scope.row)"
|
||||
v-hasPerm="['sys:user:delete']"></el-button>
|
||||
<el-button type="warning" :icon="Lock" circle plain @click="resetPassword(scope.row)"></el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize" @pagination="handleQuery" />
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 添加或修改参数配置对话框 -->
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="600px" append-to-body @close="cancel">
|
||||
<el-form ref="dataFormRef" :model="formData" :rules="rules" label-width="80px">
|
||||
<el-form-item label="用户名" prop="username">
|
||||
<el-input :readonly="!!formData.id" v-model="formData.username" placeholder="请输入用户名" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="用户昵称" prop="nickname">
|
||||
<el-input v-model="formData.nickname" placeholder="请输入用户昵称" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="所属部门" prop="deptId">
|
||||
<el-tree-select v-model="formData.deptId" placeholder="请选择所属部门" :data="deptOptions" filterable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="手机号码" prop="mobile">
|
||||
<el-input v-model="formData.mobile" placeholder="请输入手机号码" maxlength="11" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="邮箱" prop="email">
|
||||
<el-input v-model="formData.email" placeholder="请输入邮箱" maxlength="50" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-radio-group v-model="formData.status">
|
||||
<el-radio :label="1">正常</el-radio>
|
||||
<el-radio :label="0">禁用</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="用户性别" prop="gender">
|
||||
<el-select v-model="formData.gender" placeholder="请选择">
|
||||
<el-option label="未知" :value="0" />
|
||||
<el-option label="男" :value="1" />
|
||||
<el-option label="女" :value="2" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="角色" prop="roleIds">
|
||||
<el-select v-model="formData.roleIds" multiple placeholder="请选择">
|
||||
<el-option v-for="item in roleOptions" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog :title="importDialog.title" v-model="importDialog.visible" width="600px" append-to-body
|
||||
@close="closeImportDialog">
|
||||
<el-form ref="importFormRef" :model="importFormData" :rules="rules" label-width="80px">
|
||||
<el-form-item label="所属部门" prop="deptId">
|
||||
<el-tree-select v-model="formData.deptId" placeholder="请选择所属部门" :data="deptOptions" filterable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="角色" prop="roleIds">
|
||||
<el-select v-model="importFormData.roleIds" multiple placeholder="请选择">
|
||||
<el-option v-for="item in roleOptions" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="Excel">
|
||||
<el-upload class="upload-demo" action="" drag :auto-upload="false"
|
||||
accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
|
||||
:file-list="excelFilelist" :on-change="handleExcelChange" :limit="1">
|
||||
<el-icon class="el-icon--upload">
|
||||
<upload-filled />
|
||||
</el-icon>
|
||||
<div class="el-upload__text">
|
||||
将文件拖到此处,或
|
||||
<em>点击上传</em>
|
||||
</div>
|
||||
<template #tip>
|
||||
<div class="el-upload__tip">xls/xlsx files </div>
|
||||
</template>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitImportForm">确 定</el-button>
|
||||
<el-button @click="closeImportDialog">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<!-- setup 无法设置组件名称,组件名称keepAlive必须 -->
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: "user"
|
||||
};
|
||||
</script>
|
||||
|
||||
<script setup lang='ts'>
|
||||
// Vue依赖
|
||||
@@ -348,10 +168,10 @@ function filterDeptNode(value: string, data: any) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 部门树节点点击
|
||||
* 部门树节点点击事件
|
||||
*/
|
||||
function handleDeptNodeClick(data: { [key: string]: any }) {
|
||||
state.queryParams.deptId = data.id;
|
||||
state.queryParams.deptId = data.value;
|
||||
handleQuery();
|
||||
}
|
||||
|
||||
@@ -572,7 +392,7 @@ async function showImportDialog() {
|
||||
state.importDialog.visible = true
|
||||
}
|
||||
|
||||
|
||||
// Excel文件上传
|
||||
function handleExcelChange(file: UploadFile) {
|
||||
if (!/\.(xlsx|xls|XLSX|XLS)$/.test(file.name)) {
|
||||
ElMessage.warning('上传Excel只能为xlsx、xls格式');
|
||||
@@ -645,6 +465,192 @@ onMounted(() => {
|
||||
loadData();
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-row :gutter="20">
|
||||
<!-- 部门树 -->
|
||||
<el-col :span="4" :xs="24">
|
||||
<el-card class="box-card">
|
||||
<el-input v-model="deptName" placeholder="部门名称" clearable :prefix-icon="Search" style="margin-bottom: 20px" />
|
||||
<el-tree ref="deptTreeRef" :data="deptOptions" :props="{ children: 'children', label: 'label', disabled: '' }"
|
||||
:expand-on-click-node="false" :filter-node-method="filterDeptNode" default-expand-all
|
||||
@node-click="handleDeptNodeClick"></el-tree>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
||||
<!-- 用户数据 -->
|
||||
<el-col :span="20" :xs="24">
|
||||
<el-card class="box-card">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-row>
|
||||
<el-col :span="18" :xs="24" >
|
||||
<el-form-item>
|
||||
<el-button type="success" :icon="Plus" @click="handleAdd" v-hasPerm="['sys:user:add']">新增</el-button>
|
||||
<el-button type="danger" :icon="Delete" :disabled="multiple" @click="handleDelete"
|
||||
v-hasPerm="['sys:user:delete']">删除</el-button>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="keywords">
|
||||
<el-input v-model="queryParams.keywords" placeholder="用户名/昵称/手机号" clearable style="width: 200px"
|
||||
@keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="status">
|
||||
<el-select v-model="queryParams.status" placeholder="用户状态" clearable style="width: 200px">
|
||||
<el-option label="正常" value="1" />
|
||||
<el-option label="停用" value="0" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button :icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="6" :xs="24" style="text-align: right;">
|
||||
<el-form-item>
|
||||
<el-dropdown split-button style="margin-left: 12px;">
|
||||
导入
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item :icon="Download" @click="handleDownloadTemplate">下载模板</el-dropdown-item>
|
||||
<el-dropdown-item :icon="Top" @click="showImportDialog">导入数据</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
<el-button :icon="Download" style="margin-left: 12px;" @click="handleExport">导出</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
|
||||
<el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="50" align="center" />
|
||||
<el-table-column key="id" label="用户编号" align="center" prop="id" />
|
||||
<el-table-column key="username" label="用户名" align="center" prop="username" />
|
||||
<el-table-column label="用户昵称" align="center" prop="nickname" />
|
||||
|
||||
<el-table-column label="性别" align="center" prop="gender" />
|
||||
|
||||
<el-table-column label="部门" align="center" prop="deptName" />
|
||||
<el-table-column label="手机号码" align="center" prop="mobile" width="120" />
|
||||
|
||||
<el-table-column label="状态" align="center" prop="status">
|
||||
<template #default="scope">
|
||||
<el-switch v-model="scope.row.status" :inactive-value="0" :active-value="1"
|
||||
@change="handleStatusChange(scope.row)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="gmtCreate" width="180"></el-table-column>
|
||||
<el-table-column label="操作" align="center" width="150">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" :icon="Edit" circle plain @click="handleUpdate(scope.row)"
|
||||
v-hasPerm="['sys:user:edit']"></el-button>
|
||||
<el-button type="danger" :icon="Delete" circle plain @click="handleDelete(scope.row)"
|
||||
v-hasPerm="['sys:user:delete']"></el-button>
|
||||
<el-button type="warning" :icon="Lock" circle plain @click="resetPassword(scope.row)"></el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize" @pagination="handleQuery" />
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 添加或修改参数配置对话框 -->
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="600px" append-to-body @close="cancel">
|
||||
<el-form ref="dataFormRef" :model="formData" :rules="rules" label-width="80px">
|
||||
<el-form-item label="用户名" prop="username">
|
||||
<el-input :readonly="!!formData.id" v-model="formData.username" placeholder="请输入用户名" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="用户昵称" prop="nickname">
|
||||
<el-input v-model="formData.nickname" placeholder="请输入用户昵称" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="所属部门" prop="deptId">
|
||||
<el-tree-select v-model="formData.deptId" placeholder="请选择所属部门" :data="deptOptions" filterable check-strictly />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="手机号码" prop="mobile">
|
||||
<el-input v-model="formData.mobile" placeholder="请输入手机号码" maxlength="11" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="邮箱" prop="email">
|
||||
<el-input v-model="formData.email" placeholder="请输入邮箱" maxlength="50" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-radio-group v-model="formData.status">
|
||||
<el-radio :label="1">正常</el-radio>
|
||||
<el-radio :label="0">禁用</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="用户性别" prop="gender">
|
||||
<el-select v-model="formData.gender" placeholder="请选择">
|
||||
<el-option label="未知" :value="0" />
|
||||
<el-option label="男" :value="1" />
|
||||
<el-option label="女" :value="2" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="角色" prop="roleIds">
|
||||
<el-select v-model="formData.roleIds" multiple placeholder="请选择">
|
||||
<el-option v-for="item in roleOptions" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog :title="importDialog.title" v-model="importDialog.visible" width="600px" append-to-body
|
||||
@close="closeImportDialog">
|
||||
<el-form ref="importFormRef" :model="importFormData" :rules="rules" label-width="80px">
|
||||
<el-form-item label="部门" prop="deptId">
|
||||
<el-tree-select v-model="formData.deptId" placeholder="请选择部门" :data="deptOptions" filterable check-strictly />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="角色" prop="roleIds">
|
||||
<el-select v-model="importFormData.roleIds" multiple placeholder="请选择">
|
||||
<el-option v-for="item in roleOptions" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="Excel">
|
||||
<el-upload class="upload-demo" action="" drag :auto-upload="false"
|
||||
accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
|
||||
:file-list="excelFilelist" :on-change="handleExcelChange" :limit="1">
|
||||
<el-icon class="el-icon--upload">
|
||||
<upload-filled />
|
||||
</el-icon>
|
||||
<div class="el-upload__text">
|
||||
将文件拖到此处,或
|
||||
<em>点击上传</em>
|
||||
</div>
|
||||
<template #tip>
|
||||
<div class="el-upload__tip">xls/xlsx files </div>
|
||||
</template>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitImportForm">确 定</el-button>
|
||||
<el-button @click="closeImportDialog">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user