|
@@ -0,0 +1,332 @@
|
|
|
+<template>
|
|
|
+ <div>
|
|
|
+ <div class="tw-bg-white tw-p-5 tw-rounded-xl tw-mb-5">
|
|
|
+ <RootOrgSelect v-if="store.isSuperAdmin" v-model:value="rootOrgId" />
|
|
|
+
|
|
|
+ <span class="tw-mr-4"></span>
|
|
|
+ <a-input
|
|
|
+ v-model:value="name"
|
|
|
+ class="tw-mr-4"
|
|
|
+ style="width: 178px"
|
|
|
+ placeholder="姓名"
|
|
|
+ allowClear
|
|
|
+ ></a-input>
|
|
|
+ <span class="tw-mr-4"></span>
|
|
|
+ <a-input
|
|
|
+ v-model:value="loginName"
|
|
|
+ style="width: 178px"
|
|
|
+ placeholder="登录名"
|
|
|
+ allowClear
|
|
|
+ ></a-input>
|
|
|
+ <span class="tw-mr-4"></span>
|
|
|
+ <RoleSelect v-model:value="roleId" :root-org-id="rootOrgId" />
|
|
|
+ <StateSelect v-model:value="enable" />
|
|
|
+ <span class="tw-mr-4"></span>
|
|
|
+ <a-button @click="search">查询</a-button>
|
|
|
+
|
|
|
+ <div class="tw-mt-4">
|
|
|
+ <a-button @click="newUser">新增</a-button>
|
|
|
+ <a-button @click="importModalVisible = true">批量导入</a-button>
|
|
|
+ <a-button @click="handleExport">批量导出</a-button>
|
|
|
+ <a-button @click="handleToggleUsers(true, selectIds)"
|
|
|
+ >批量启用</a-button
|
|
|
+ >
|
|
|
+ <a-button @click="handleToggleUsers(false, selectIds)"
|
|
|
+ >批量禁用</a-button
|
|
|
+ >
|
|
|
+ <a-button @click="handleResetUsers(selectIds)">批量重置密码</a-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="tw-bg-white tw-p-5 tw-rounded-xl">
|
|
|
+ <a-table
|
|
|
+ row-key="id"
|
|
|
+ :columns="columns"
|
|
|
+ :data-source="data"
|
|
|
+ :row-selection="rowSelection"
|
|
|
+ :pagination="{
|
|
|
+ pageSize: pageSize,
|
|
|
+ current: pageNo,
|
|
|
+ total: totalElements,
|
|
|
+ showTotal: (total: number) => `总数:${total}`,
|
|
|
+ onChange: (pageNoChanged: number, pageSizeChanged: number) => {
|
|
|
+ pageNo = pageNoChanged;
|
|
|
+ pageSize = pageSizeChanged;
|
|
|
+ }
|
|
|
+ }"
|
|
|
+ >
|
|
|
+ <template #rootOrgName="{ record }">
|
|
|
+ <a>{{ record.rootOrgName }}({{ record.rootOrgCode }})</a>
|
|
|
+ </template>
|
|
|
+ <template #enable="{ text }">
|
|
|
+ <a>{{ $filters.booleanEnableDisableFilter(text) }}</a>
|
|
|
+ </template>
|
|
|
+ <template #action="{ record }">
|
|
|
+ <span>
|
|
|
+ <a-button @click="showModal(record)">编辑</a-button>
|
|
|
+ <a-button @click="handleToggleUsers(!record.enable, [record.id])">
|
|
|
+ {{ record.enable ? "禁用" : "启用" }}
|
|
|
+ </a-button>
|
|
|
+ <a-button @click="handleResetUsers([record.id])">重置密码</a-button>
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </a-table>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <a-modal
|
|
|
+ v-model:visible="visible"
|
|
|
+ title="用户信息页"
|
|
|
+ @ok="handleOk"
|
|
|
+ ok-text="确定"
|
|
|
+ cancel-text="取消"
|
|
|
+ >
|
|
|
+ <a-form>
|
|
|
+ <a-form-item v-show="store.isSuperAdmin" label="顶级机构">
|
|
|
+ <RootOrgSelect
|
|
|
+ :disabled="!!userObj.id"
|
|
|
+ v-model:value="userObj.rootOrgId"
|
|
|
+ />
|
|
|
+ </a-form-item>
|
|
|
+ <a-form-item label="姓名">
|
|
|
+ <a-input v-model:value="userObj.name"></a-input>
|
|
|
+ </a-form-item>
|
|
|
+ <a-form-item label="登录名">
|
|
|
+ <a-input
|
|
|
+ :disabled="!!userObj.id"
|
|
|
+ v-model:value="userObj.loginName"
|
|
|
+ ></a-input>
|
|
|
+ </a-form-item>
|
|
|
+ <a-form-item label="登录密码">
|
|
|
+ <a-input
|
|
|
+ :disabled="!!userObj.id"
|
|
|
+ v-model:value="userObj.password"
|
|
|
+ ></a-input>
|
|
|
+ </a-form-item>
|
|
|
+ <a-form-item label="角色">
|
|
|
+ <RoleSelect
|
|
|
+ :root-org-id="userObj.rootOrgId"
|
|
|
+ v-model:value="userObj.roleId"
|
|
|
+ />
|
|
|
+ </a-form-item>
|
|
|
+ <a-form-item label="状态">
|
|
|
+ <a-radio-group v-model:value="userObj.enable">
|
|
|
+ <a-radio :value="true">启用</a-radio>
|
|
|
+ <a-radio :value="false">禁用</a-radio>
|
|
|
+ </a-radio-group>
|
|
|
+ </a-form-item>
|
|
|
+ </a-form>
|
|
|
+ </a-modal>
|
|
|
+
|
|
|
+ <a-modal
|
|
|
+ v-model:visible="importModalVisible"
|
|
|
+ title="批量用户导入"
|
|
|
+ @ok="handleImport"
|
|
|
+ ok-text="确定"
|
|
|
+ cancel-text="取消"
|
|
|
+ >
|
|
|
+ <a-form>
|
|
|
+ <a-form-item label="顶级机构">
|
|
|
+ <RootOrgSelect
|
|
|
+ v-show="store.isSuperAdmin"
|
|
|
+ v-model:value="userObj.rootOrgId"
|
|
|
+ />
|
|
|
+ </a-form-item>
|
|
|
+ <a-form-item label="文件地址">
|
|
|
+ <input id="file-input" :multiple="false" type="file" />
|
|
|
+ </a-form-item>
|
|
|
+ </a-form>
|
|
|
+ </a-modal>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup lang="ts">
|
|
|
+import {
|
|
|
+ exportUsers,
|
|
|
+ getUserList,
|
|
|
+ importUsers,
|
|
|
+ resetPasswords,
|
|
|
+ toggleUsers,
|
|
|
+ updateUser,
|
|
|
+} from "@/api/userManagementPage";
|
|
|
+import { useMainStore } from "@/store";
|
|
|
+import { message, Modal } from "ant-design-vue";
|
|
|
+import { watch, onMounted, ref, reactive, toRaw } from "vue-demi";
|
|
|
+
|
|
|
+const store = useMainStore();
|
|
|
+store.currentLocation = "基础管理 / 用户管理";
|
|
|
+
|
|
|
+let rootOrgId = $ref(undefined as unknown as number);
|
|
|
+let roleId = $ref(undefined as unknown as number);
|
|
|
+let loginName = $ref("");
|
|
|
+let name = $ref("");
|
|
|
+let enable = $ref(undefined as undefined | boolean);
|
|
|
+
|
|
|
+let data = $ref([]);
|
|
|
+let pageSize = $ref(10);
|
|
|
+let pageNo = $ref(1);
|
|
|
+let totalElements = $ref(0);
|
|
|
+
|
|
|
+async function search() {
|
|
|
+ await fetchData();
|
|
|
+}
|
|
|
+
|
|
|
+watch(() => [pageNo, pageSize], fetchData);
|
|
|
+
|
|
|
+async function fetchData() {
|
|
|
+ const res = await getUserList({
|
|
|
+ loginName,
|
|
|
+ name,
|
|
|
+ enable,
|
|
|
+ roleId,
|
|
|
+ rootOrgId,
|
|
|
+ pageSize,
|
|
|
+ pageNo,
|
|
|
+ });
|
|
|
+ // console.log(res);
|
|
|
+ data = res.data.content;
|
|
|
+ pageNo = res.data.pageNo;
|
|
|
+ pageSize = res.data.pageSize;
|
|
|
+ totalElements = res.data.totalElements;
|
|
|
+}
|
|
|
+
|
|
|
+const columns = [
|
|
|
+ {
|
|
|
+ title: "顶级机构",
|
|
|
+ dataIndex: "rootOrgName",
|
|
|
+ width: 150,
|
|
|
+ slots: { customRender: "rootOrgName" },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: "姓名",
|
|
|
+ dataIndex: "name",
|
|
|
+ width: 150,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: "登录名",
|
|
|
+ dataIndex: "loginName",
|
|
|
+ width: 150,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: "角色",
|
|
|
+ dataIndex: "roleName",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: "状态",
|
|
|
+ dataIndex: "enable",
|
|
|
+ slots: { customRender: "enable" },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: "创建时间",
|
|
|
+ dataIndex: "createTime",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: "创建人",
|
|
|
+ dataIndex: "creator",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: "更新时间",
|
|
|
+ dataIndex: "updateTime",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: "更新人",
|
|
|
+ dataIndex: "updater",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: "Action",
|
|
|
+ key: "action",
|
|
|
+ slots: { customRender: "action" },
|
|
|
+ },
|
|
|
+];
|
|
|
+
|
|
|
+onMounted(async () => {
|
|
|
+ rootOrgId = store.userInfo.rootOrgId;
|
|
|
+ await search();
|
|
|
+});
|
|
|
+
|
|
|
+const visible = ref<boolean>(false);
|
|
|
+
|
|
|
+const showModal = (record: any) => {
|
|
|
+ Object.assign(userObj, record);
|
|
|
+ visible.value = true;
|
|
|
+};
|
|
|
+
|
|
|
+const handleOk = async (e: MouseEvent) => {
|
|
|
+ await updateUser(toRaw(userObj));
|
|
|
+ visible.value = false;
|
|
|
+ await search();
|
|
|
+};
|
|
|
+
|
|
|
+const initUser = {
|
|
|
+ id: undefined,
|
|
|
+ code: "",
|
|
|
+ name: "",
|
|
|
+ loginName: "",
|
|
|
+ password: "",
|
|
|
+ enable: true,
|
|
|
+ roleId,
|
|
|
+ rootOrgId: store.userInfo.rootOrgId,
|
|
|
+};
|
|
|
+const userObj = reactive({ ...initUser });
|
|
|
+
|
|
|
+const newUser = async () => {
|
|
|
+ Object.assign(userObj, initUser);
|
|
|
+ showModal(userObj);
|
|
|
+};
|
|
|
+
|
|
|
+function checkEmpty(): boolean {
|
|
|
+ if (selectIds && selectIds.length > 0) {
|
|
|
+ return false;
|
|
|
+ } else {
|
|
|
+ message.warn({ content: "请先选择行" });
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+}
|
|
|
+async function handleToggleUsers(enable: boolean, ids: number[]) {
|
|
|
+ if (checkEmpty()) return;
|
|
|
+ await toggleUsers(enable, ids);
|
|
|
+ await search();
|
|
|
+}
|
|
|
+
|
|
|
+async function handleResetUsers(ids: number[]) {
|
|
|
+ if (checkEmpty()) return;
|
|
|
+ Modal.confirm({
|
|
|
+ title: "提示",
|
|
|
+ content: "确认重置?",
|
|
|
+ cancelText: "取消",
|
|
|
+ okText: "确定",
|
|
|
+ onOk: async () => {
|
|
|
+ await resetPasswords(ids);
|
|
|
+ await search();
|
|
|
+ },
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+/** <handleImport> */
|
|
|
+let importModalVisible = ref<boolean>(false);
|
|
|
+async function handleImport() {
|
|
|
+ const files = (document.querySelector("#file-input") as HTMLInputElement)
|
|
|
+ .files;
|
|
|
+ const fileToImport = files && files[0];
|
|
|
+ if (!fileToImport) {
|
|
|
+ message.warn({ content: "请选择文件" });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ await importUsers(rootOrgId, fileToImport);
|
|
|
+ message.success({ content: "导入成功" });
|
|
|
+}
|
|
|
+/** </handleImport> */
|
|
|
+
|
|
|
+async function handleExport() {
|
|
|
+ await exportUsers({ rootOrgId, name, loginName, roleId, enable });
|
|
|
+ message.success({ content: "导出成功" });
|
|
|
+}
|
|
|
+
|
|
|
+let selectIds = $ref<number[]>([]);
|
|
|
+const rowSelection = {
|
|
|
+ onChange: (selectedRowKeys: (string | number)[]) => {
|
|
|
+ console.log(`selectedRowKeys: ${selectedRowKeys}`);
|
|
|
+ selectIds = selectedRowKeys as number[];
|
|
|
+ },
|
|
|
+};
|
|
|
+</script>
|