Kaynağa Gözat

feat:按钮列表

snow 2 yıl önce
ebeveyn
işleme
6007da5537

+ 27 - 0
src/api/system/buttonOperator/index.ts

@@ -0,0 +1,27 @@
+// 菜单删除
+import { http } from "/@/utils/http";
+import { loadEnv } from "@build/index";
+const { VITE_PROXY_DOMAIN_REAL, VITE_PROXY_USER_REAL } = loadEnv();
+
+const userAPi = VITE_PROXY_DOMAIN_REAL;
+const yewuApi = VITE_PROXY_USER_REAL + "/admin/";
+
+// 根据菜单id获取所有功能
+export const httpList = (id: string): any => {
+  return http.request("post", `${yewuApi}menuaction`, {
+    data: {
+      id
+    }
+  });
+};
+
+// 功能状态
+export const httpStatus = ({ id, status}:{ id: string, status: string }): any => {
+  return http.request("post", `${yewuApi}menuactionstatus`, { data: { id,status } });
+};
+
+
+// 菜单删除
+export const httpDelete = (id:string): any => {
+  return http.request("post", `${yewuApi}menuactiondel`, { data: {id} });
+};

+ 15 - 88
src/views/system/oplog/columns.tsx

@@ -1,77 +1,44 @@
 import { ref } from "vue";
 import dayjs from "dayjs";
-import { ElMessageBox } from "element-plus";
-import { Switch, message } from "@pureadmin/components";
 
 export function useColumns() {
-  const switchLoadMap = ref({});
-
   const columns = ref([
     {
       type: "selection",
-      width: 55,
+      minWidth: 55,
+      align: "left",
       hide: ({ checkList }) => !checkList.includes("勾选列")
     },
     {
       label: "序号",
       type: "index",
-      width: 70,
+      minWidth: 60,
+      align: "left",
       hide: ({ checkList }) => !checkList.includes("序号列")
     },
     {
-      label: "用户编号",
-      prop: "id"
-    },
-    {
-      label: "用户名称",
-      prop: "username"
-    },
-    {
-      label: "用户昵称",
-      prop: "nickname"
+      label: "按钮名称",
+      prop: "action_name",
+      minWidth: 180,
+      align: "left"
     },
     {
-      label: "性别",
-      prop: "sex",
+      label: "状态",
+      prop: "status",
+      minWidth: 80,
       cellRenderer: ({ row, props }) => (
         <el-tag
           size={props.size}
-          type={row.sex === 1 ? "danger" : ""}
+          type={row.status + "" === "1" ? "success" : "danger"}
           effect="plain"
         >
-          {row.sex === 1 ? "女" : "男"}
+          {row.status + "" === "0" ? "禁用" : "启用"}
         </el-tag>
       )
     },
-    {
-      label: "部门",
-      prop: "dept",
-      formatter: ({ dept }) => dept.name
-    },
-    {
-      label: "手机号码",
-      prop: "mobile"
-    },
-    {
-      label: "状态",
-      prop: "status",
-      width: 130,
-      cellRenderer: scope => (
-        <Switch
-          size={scope.props.size === "small" ? "small" : "default"}
-          loading={switchLoadMap.value[scope.index]?.loading}
-          v-model:checked={scope.row.status}
-          checkedValue={1}
-          unCheckedValue={0}
-          checked-children="已开启"
-          un-checked-children="已关闭"
-          onChange={() => onChange(scope)}
-        />
-      )
-    },
     {
       label: "创建时间",
-      width: 180,
+      minWidth: 180,
       prop: "createTime",
       formatter: ({ createTime }) =>
         dayjs(createTime).format("YYYY-MM-DD HH:mm:ss")
@@ -79,51 +46,11 @@ export function useColumns() {
     {
       label: "操作",
       fixed: "right",
-      width: 180,
+      minWidth: 140,
       slot: "operation"
     }
   ]);
 
-  function onChange({ row, index }) {
-    ElMessageBox.confirm(
-      `确认要<strong>${
-        row.status === 0 ? "停用" : "启用"
-      }</strong><strong style='color:var(--el-color-primary)'>${
-        row.username
-      }</strong>用户吗?`,
-      "系统提示",
-      {
-        confirmButtonText: "确定",
-        cancelButtonText: "取消",
-        type: "warning",
-        dangerouslyUseHTMLString: true,
-        draggable: true
-      }
-    )
-      .then(() => {
-        switchLoadMap.value[index] = Object.assign(
-          {},
-          switchLoadMap.value[index],
-          {
-            loading: true
-          }
-        );
-        setTimeout(() => {
-          switchLoadMap.value[index] = Object.assign(
-            {},
-            switchLoadMap.value[index],
-            {
-              loading: false
-            }
-          );
-          message.success("已成功修改用户状态");
-        }, 300);
-      })
-      .catch(() => {
-        row.status === 0 ? (row.status = 1) : (row.status = 0);
-      });
-  }
-
   return {
     columns
   };

+ 162 - 0
src/views/system/oplog/components/action-table.vue

@@ -0,0 +1,162 @@
+<script setup lang="ts">
+import { ref } from "vue";
+import { useColumns } from "./../columns";
+import { handleTree } from "@pureadmin/utils";
+import { httpList, httpStatus, httpDelete } from "/@/api/system/buttonOperator";
+import { ElMessage } from "element-plus";
+import { TableProBar } from "/@/components/ReTable";
+import { useRenderIcon } from "/@/components/ReIcon/src/hooks";
+import { useNav } from "/@/layout/hooks/nav";
+
+const dataList = ref([]);
+const loading = ref(false);
+const itemId = ref("");
+const tableRef = ref();
+const isDetails = ref("add");
+const currentActionId = ref("");
+const { columns } = useColumns();
+const { logout } = useNav();
+
+const emit = defineEmits(["edit"]);
+
+function actionWithSuccess({
+  code,
+  message,
+  handler
+}: {
+  code: number;
+  message: string;
+  handler: () => void;
+}) {
+  const c = Number(code);
+  if (c === 0) {
+    handler();
+  } else if (c > 100 && c < 140) {
+    logout();
+  } else {
+    ElMessage.error(message);
+  }
+}
+
+//按钮状态更新
+const handleUpdate = async row => {
+  const { id, status } = row;
+  const { code, message } = await httpStatus({
+    id,
+    status: status + "" === "1" ? "0" : "1"
+  });
+  actionWithSuccess({
+    code,
+    message,
+    handler: () => onSearch(currentActionId.value)
+  });
+};
+
+//删除按钮
+const handleDelete = async row => {
+  const { id } = row;
+  const { code, message } = await httpDelete(id);
+  actionWithSuccess({
+    code,
+    message,
+    handler: () => onSearch(currentActionId.value)
+  });
+};
+
+async function onSearch(id: string) {
+  loading.value = true;
+  const { code, data, message } = await httpList(id);
+  actionWithSuccess({
+    code,
+    message,
+    handler: () => (dataList.value = handleTree(data ?? []))
+  });
+  loading.value = false;
+  currentActionId.value = id;
+}
+
+//编辑
+function editItem(id, type, item) {
+  emit("edit");
+}
+
+defineExpose({
+  onSearch
+});
+</script>
+<template>
+  <TableProBar
+    :title="'按钮列表'"
+    :loading="loading"
+    :tableRef="tableRef?.getTableRef()"
+    :dataList="dataList"
+    @refresh="onSearch"
+  >
+    <template #buttons> </template>
+    <template v-slot="{ size, checkList }">
+      <PureTable
+        ref="tableRef"
+        border
+        align="left"
+        row-key="id"
+        table-layout="auto"
+        default-expand-all
+        :size="size"
+        :data="dataList"
+        :columns="columns"
+        :checkList="checkList"
+        :header-cell-style="{ background: '#fafafa', color: '#606266' }"
+      >
+        <template #operation="{ row }">
+          <el-button
+            class="reset-margin"
+            link
+            type="primary"
+            :size="size"
+            :icon="useRenderIcon('edits')"
+            @click="() => editItem"
+          />
+          <el-popconfirm
+            :title="row.status === '1' ? '改为禁用?' : '改为启用?'"
+            @confirm="handleUpdate(row)"
+          >
+            <template #reference>
+              <el-button
+                class="reset-margin"
+                link
+                type="primary"
+                :size="size"
+                :icon="
+                  useRenderIcon(
+                    row.status === '1'
+                      ? 'close-circle-line'
+                      : 'checkbox-circle-line'
+                  )
+                "
+              />
+            </template>
+          </el-popconfirm>
+          <el-popconfirm title="是否确认删除?" @confirm="handleDelete(row)">
+            <template #reference>
+              <el-button
+                class="reset-margin"
+                link
+                type="primary"
+                :size="size"
+                :icon="useRenderIcon('delete')"
+              />
+            </template>
+          </el-popconfirm>
+          <el-button
+            v-if="row.menu_type + '' === '1'"
+            class="reset-margin"
+            link
+            type="primary"
+            :size="size"
+            :icon="useRenderIcon('add')"
+          />
+        </template>
+      </PureTable>
+    </template>
+  </TableProBar>
+</template>

+ 13 - 0
src/views/system/oplog/components/edit-dialog.vue

@@ -0,0 +1,13 @@
+<script setup lang="ts"></script>
+
+<template>
+  <div>
+    <el-dialog :model-value="true">
+      <el-form>
+        <el-form-item label="按钮名称">
+          <el-input />
+        </el-form-item>
+      </el-form>
+    </el-dialog>
+  </div>
+</template>

+ 42 - 0
src/views/system/oplog/components/menu-tree.vue

@@ -0,0 +1,42 @@
+<script setup lang="ts">
+import { ref, watch } from "vue";
+import { httpList } from "/@/api/system/menuOperator";
+import type { IMenuTree } from "../types";
+import { ElTree } from "element-plus";
+
+const defaultProps = {
+  label: "menu_name",
+  children: "child"
+};
+
+const emit = defineEmits(["treeSelectChange"]);
+
+const treeData = ref<Array<IMenuTree>>([]);
+const treeRef = ref<InstanceType<typeof ElTree>>(null);
+
+//获取菜单树列表
+async function initMenuList() {
+  const { data: list } = await httpList({});
+  treeData.value = list;
+}
+
+//选择节点
+function handleSelect(node) {
+  emit("treeSelectChange", node);
+}
+
+initMenuList();
+</script>
+
+<template>
+  <div
+    class="max-w-280px w-[280px] h-full min-h-780px bg-white p-2 mt-24px mr-10px"
+  >
+    <el-tree
+      ref="treeRef"
+      :props="defaultProps"
+      :data="treeData"
+      @current-change="handleSelect"
+    />
+  </div>
+</template>

+ 22 - 212
src/views/system/oplog/index.vue

@@ -1,222 +1,32 @@
 <script setup lang="ts">
-import tree from "./tree.vue";
-import { useColumns } from "./columns";
-import { getUserList } from "/@/api/system";
-import { reactive, ref, onMounted } from "vue";
-import { type FormInstance } from "element-plus";
-import { TableProBar } from "/@/components/ReTable";
-import { type PaginationProps } from "@pureadmin/table";
-import { useRenderIcon } from "/@/components/ReIcon/src/hooks";
-
-defineOptions({
-  name: "User"
-});
-
-const form = reactive({
-  username: "",
-  mobile: "",
-  status: ""
-});
-let dataList = ref([]);
-let loading = ref(true);
-const { columns } = useColumns();
-
-const formRef = ref<FormInstance>();
-
-const pagination = reactive<PaginationProps>({
-  total: 0,
-  pageSize: 10,
-  currentPage: 1,
-  background: true
-});
-
-function handleUpdate(row) {
-  console.log(row);
-}
-
-function handleDelete(row) {
-  console.log(row);
-}
-
-function handleCurrentChange(val: number) {
-  console.log(`current page: ${val}`);
+import { ref } from "vue";
+import MenuTree from "./components/menu-tree.vue";
+import ActionTable from "./components/action-table.vue";
+import EditModel from "./components/edit-dialog.vue";
+import { IMenuTree } from "./types";
+
+const actionTableRef = ref<InstanceType<typeof ActionTable>>(null);
+const PAGE_TYPE = "2";
+
+//节点选择
+function handleTreeNodeSelect(node: IMenuTree) {
+  const { menu_type, id } = node;
+  const isPage = menu_type === PAGE_TYPE;
+  if (!isPage) return;
+  //选择页面进行搜索
+  actionTableRef.value.onSearch(id);
 }
 
-function handleSizeChange(val: number) {
-  console.log(`${val} items per page`);
+//编辑按钮
+function handleEdit() {
+  console.log(111);
 }
-
-function handleSelectionChange(val) {
-  console.log("handleSelectionChange", val);
-}
-
-async function onSearch() {
-  loading.value = true;
-  let { data } = await getUserList();
-  dataList.value = data.list;
-  pagination.total = data.total;
-  setTimeout(() => {
-    loading.value = false;
-  }, 500);
-}
-
-const resetForm = (formEl: FormInstance | undefined) => {
-  if (!formEl) return;
-  formEl.resetFields();
-  onSearch();
-};
-
-onMounted(() => {
-  onSearch();
-});
 </script>
 
 <template>
   <div class="main flex">
-    <tree />
-    <div class="flex-1 ml-4">
-      <el-form
-        ref="formRef"
-        :inline="true"
-        :model="form"
-        class="bg-white w-99/100 pl-8 pt-4"
-      >
-        <el-form-item label="用户名称:" prop="username">
-          <el-input
-            v-model="form.username"
-            placeholder="请输入用户名称"
-            clearable
-          />
-        </el-form-item>
-        <el-form-item label="手机号码:" prop="mobile">
-          <el-input
-            v-model="form.mobile"
-            placeholder="请输入手机号码"
-            clearable
-          />
-        </el-form-item>
-        <el-form-item label="状态:" prop="status">
-          <el-select v-model="form.status" placeholder="请选择" clearable>
-            <el-option label="已开启" value="1" />
-            <el-option label="已关闭" value="0" />
-          </el-select>
-        </el-form-item>
-        <el-form-item>
-          <el-button
-            type="primary"
-            :icon="useRenderIcon('search')"
-            :loading="loading"
-            @click="onSearch"
-          >
-            搜索
-          </el-button>
-          <el-button
-            :icon="useRenderIcon('refresh')"
-            @click="resetForm(formRef)"
-          >
-            重置
-          </el-button>
-        </el-form-item>
-      </el-form>
-
-      <TableProBar
-        title="用户管理"
-        :loading="loading"
-        :dataList="dataList"
-        @refresh="onSearch"
-      >
-        <template #buttons>
-          <el-button type="primary" :icon="useRenderIcon('add')">
-            新增用户
-          </el-button>
-        </template>
-        <template v-slot="{ size, checkList }">
-          <PureTable
-            border
-            align="center"
-            table-layout="auto"
-            :size="size"
-            :data="dataList"
-            :columns="columns"
-            :checkList="checkList"
-            :pagination="pagination"
-            :paginationSmall="size === 'small' ? true : false"
-            :header-cell-style="{ background: '#fafafa', color: '#606266' }"
-            @selection-change="handleSelectionChange"
-            @size-change="handleSizeChange"
-            @current-change="handleCurrentChange"
-          >
-            <template #operation="{ row }">
-              <el-button
-                class="reset-margin"
-                link
-                type="primary"
-                :size="size"
-                @click="handleUpdate(row)"
-                :icon="useRenderIcon('edits')"
-              >
-                修改
-              </el-button>
-              <el-popconfirm title="是否确认删除?">
-                <template #reference>
-                  <el-button
-                    class="reset-margin"
-                    link
-                    type="primary"
-                    :size="size"
-                    :icon="useRenderIcon('delete')"
-                    @click="handleDelete(row)"
-                  >
-                    删除
-                  </el-button>
-                </template>
-              </el-popconfirm>
-              <el-dropdown>
-                <el-button
-                  class="ml-3"
-                  link
-                  type="primary"
-                  :size="size"
-                  @click="handleUpdate(row)"
-                  :icon="useRenderIcon('more')"
-                />
-                <template #dropdown>
-                  <el-dropdown-menu>
-                    <el-dropdown-item>
-                      <el-button
-                        class="reset-margin !h-20px !text-gray-500"
-                        link
-                        type="primary"
-                        :size="size"
-                        :icon="useRenderIcon('password')"
-                      >
-                        重置密码
-                      </el-button>
-                    </el-dropdown-item>
-                    <el-dropdown-item>
-                      <el-button
-                        class="reset-margin !h-20px !text-gray-500"
-                        link
-                        type="primary"
-                        :size="size"
-                        :icon="useRenderIcon('role')"
-                      >
-                        分配角色
-                      </el-button>
-                    </el-dropdown-item>
-                  </el-dropdown-menu>
-                </template>
-              </el-dropdown>
-            </template>
-          </PureTable>
-        </template>
-      </TableProBar>
-    </div>
+    <MenuTree @tree-select-change="handleTreeNodeSelect" />
+    <ActionTable ref="actionTableRef" @edit="handleEdit" />
+    <EditModel />
   </div>
 </template>
-
-<style scoped lang="scss">
-:deep(.el-dropdown-menu__item i) {
-  margin: 0;
-}
-</style>

+ 0 - 190
src/views/system/oplog/tree.vue

@@ -1,190 +0,0 @@
-<script lang="ts" setup>
-import type { ElTree } from "element-plus";
-import { getDeptList } from "/@/api/system";
-import { handleTree } from "@pureadmin/utils";
-import { useRenderIcon } from "/@/components/ReIcon/src/hooks";
-import { ref, watch, onMounted, getCurrentInstance } from "vue";
-
-interface Tree {
-  id: number;
-  name: string;
-  highlight?: boolean;
-  children?: Tree[];
-}
-const defaultProps = {
-  children: "children",
-  label: "name"
-};
-
-const treeData = ref([]);
-const searchValue = ref("");
-const { proxy } = getCurrentInstance();
-const treeRef = ref<InstanceType<typeof ElTree>>();
-
-let highlightMap = ref({});
-
-const filterNode = (value: string, data: Tree) => {
-  if (!value) return true;
-  return data.name.includes(value);
-};
-
-function nodeClick(value) {
-  const nodeId = value.$treeNodeId;
-  highlightMap.value[nodeId] = highlightMap.value[nodeId]?.highlight
-    ? Object.assign({ id: nodeId }, highlightMap.value[nodeId], {
-        highlight: false
-      })
-    : Object.assign({ id: nodeId }, highlightMap.value[nodeId], {
-        highlight: true
-      });
-  Object.values(highlightMap.value).forEach((v: Tree) => {
-    if (v.id !== nodeId) {
-      v.highlight = false;
-    }
-  });
-}
-
-function toggleRowExpansionAll(status) {
-  // @ts-expect-error
-  let nodes = proxy.$refs["treeRef"].store._getAllNodes();
-  for (var i = 0; i < nodes.length; i++) {
-    nodes[i].expanded = status;
-  }
-}
-
-// 重置状态(选中状态、搜索框值、树初始化)
-function onReset() {
-  highlightMap.value = {};
-  searchValue.value = "";
-  toggleRowExpansionAll(true);
-}
-
-watch(searchValue, val => {
-  treeRef.value!.filter(val);
-});
-
-onMounted(async () => {
-  let { data } = await getDeptList();
-  treeData.value = handleTree(data);
-});
-</script>
-
-<template>
-  <div class="max-w-260px h-full min-h-780px bg-white">
-    <div class="flex items-center h-34px">
-      <p class="flex-1 ml-2 font-bold text-base truncate" title="部门列表">
-        部门列表
-      </p>
-      <el-input
-        style="flex: 2"
-        size="small"
-        v-model="searchValue"
-        placeholder="请输入部门名称"
-        clearable
-      >
-        <template #suffix>
-          <el-icon class="el-input__icon">
-            <IconifyIconOffline
-              v-show="searchValue.length === 0"
-              icon="search"
-            />
-          </el-icon>
-        </template>
-      </el-input>
-      <el-dropdown>
-        <IconifyIconOffline
-          class="w-28px cursor-pointer"
-          width="18px"
-          icon="more-vertical"
-        />
-        <template #dropdown>
-          <el-dropdown-menu>
-            <el-dropdown-item>
-              <el-button
-                class="reset-margin !h-20px !text-gray-500"
-                link
-                type="primary"
-                :icon="useRenderIcon('expand')"
-                @click="toggleRowExpansionAll(true)"
-              >
-                展开全部
-              </el-button>
-            </el-dropdown-item>
-            <el-dropdown-item>
-              <el-button
-                class="reset-margin !h-20px !text-gray-500"
-                link
-                type="primary"
-                :icon="useRenderIcon('unExpand')"
-                @click="toggleRowExpansionAll(false)"
-              >
-                折叠全部
-              </el-button>
-            </el-dropdown-item>
-            <el-dropdown-item>
-              <el-button
-                class="reset-margin !h-20px !text-gray-500"
-                link
-                type="primary"
-                :icon="useRenderIcon('reset')"
-                @click="onReset"
-              >
-                重置状态
-              </el-button>
-            </el-dropdown-item>
-          </el-dropdown-menu>
-        </template>
-      </el-dropdown>
-    </div>
-    <el-divider />
-    <el-tree
-      ref="treeRef"
-      :data="treeData"
-      node-key="id"
-      size="small"
-      :props="defaultProps"
-      default-expand-all
-      :expand-on-click-node="false"
-      :filter-node-method="filterNode"
-      @node-click="nodeClick"
-    >
-      <template #default="{ node, data }">
-        <span
-          :class="[
-            'pl-1',
-            'pr-1',
-            'rounded',
-            'flex',
-            'items-center',
-            'select-none',
-            searchValue.trim().length > 0 &&
-              node.label.includes(searchValue) &&
-              'text-red-500'
-          ]"
-          :style="{
-            background: highlightMap[node.id]?.highlight
-              ? 'var(--el-color-primary-light-7)'
-              : 'transparent'
-          }"
-        >
-          <IconifyIconOffline
-            :icon="
-              data.type === 1
-                ? 'office-building'
-                : data.type === 2
-                ? 'location-company'
-                : 'dept'
-            "
-          />
-          {{ node.label }}
-        </span>
-      </template>
-    </el-tree>
-  </div>
-</template>
-
-<style lang="scss" scoped>
-:deep(.el-divider) {
-  margin: 0;
-}
-</style>

+ 14 - 0
src/views/system/oplog/types.ts

@@ -0,0 +1,14 @@
+export interface IMenuTree {
+  id: string;
+  is_private: string;
+  is_show: string;
+  menu_img: string;
+  menu_name: string;
+  menu_route: string;
+  menu_type: "1" | "2";
+  menu_url: string;
+  pid: string;
+  status: string;
+  weight: string;
+  children:Array<IMenuTree>
+}