diff --git a/package.json b/package.json
index 9b0d6c27c4d4763209dfd376ad1cb4cd31223d58..00311f5de5c446ebc7e83961e4603afd99892b0c 100644
--- a/package.json
+++ b/package.json
@@ -17,7 +17,7 @@
"react-dom": "^18.2.0"
},
"devDependencies": {
- "@ainiteam/quick-react-ui": "0.0.0-alpha.5",
+ "@ainiteam/quick-react-ui": "0.0.0-alpha.6",
"@ant-design/icons": "^5.2.6",
"@reduxjs/toolkit": "^2.0.1",
"@types/crypto-js": "^4.2.1",
diff --git a/src/views/auth/role/components/DialogProgress/index.tsx b/src/views/auth/role/components/DialogProgress/index.tsx
index 6c9940d136ebb8edb41477390894e5f3f1367768..43eff0f15a9d1c447954b1c1a2234f1c2c575057 100644
--- a/src/views/auth/role/components/DialogProgress/index.tsx
+++ b/src/views/auth/role/components/DialogProgress/index.tsx
@@ -1,7 +1,242 @@
-const DialogProgress: React.FC = () => {
- return (
-
DialogProgress
- );
+import { getApiPermission, getMenuPermission } from "@/api/auth";
+import { getApiList } from "@/api/system/api";
+import { getMenuList } from "@/api/system/menu";
+import { IMenuTree } from "@/types";
+import { listToTableTree, listToTree } from "@/utils";
+import { Steps, Tree } from "antd";
+import { useEffect, useState } from "react";
+
+type RoleProp = {
+ role: any;
+};
+
+const DialogProgress: React.FC = (props: RoleProp) => {
+ const { role } = props;
+ const [current, setCurrent] = useState(0);
+ const [menuTreeData, setMenuTreeData] = useState([]);
+ const [menuTreeList, setMenuTreeList] = useState([]);
+ const [apiTreeList, setApiTreeList] = useState([]);
+ const [apiTreeData, setApiTreeData] = useState([]);
+
+ const treeData = [
+ {
+ title: "0-0",
+ key: "0-0",
+ children: [
+ {
+ title: "0-0-0",
+ key: "0-0-0",
+ children: [
+ {
+ title: "0-0-0-0",
+ key: "0-0-0-0",
+ },
+ {
+ title: "0-0-0-1",
+ key: "0-0-0-1",
+ },
+ {
+ title: "0-0-0-2",
+ key: "0-0-0-2",
+ },
+ ],
+ },
+ {
+ title: "0-0-1",
+ key: "0-0-1",
+ children: [
+ {
+ title: "0-0-1-0",
+ key: "0-0-1-0",
+ },
+ {
+ title: "0-0-1-1",
+ key: "0-0-1-1",
+ },
+ {
+ title: "0-0-1-2",
+ key: "0-0-1-2",
+ },
+ ],
+ },
+ {
+ title: "0-0-2",
+ key: "0-0-2",
+ },
+ ],
+ },
+ {
+ title: "0-1",
+ key: "0-1",
+ children: [
+ {
+ title: "0-1-0-0",
+ key: "0-1-0-0",
+ },
+ {
+ title: "0-1-0-1",
+ key: "0-1-0-1",
+ },
+ {
+ title: "0-1-0-2",
+ key: "0-1-0-2",
+ },
+ ],
+ },
+ {
+ title: "0-2",
+ key: "0-2",
+ },
+ ];
+ const [expandedKeys, setExpandedKeys] = useState(["0-0-0", "0-0-1"]);
+ const [checkedKeys, setCheckedKeys] = useState(["0-0-0"]);
+ const [selectedKeys, setSelectedKeys] = useState([]);
+ const [autoExpandParent, setAutoExpandParent] = useState(true);
+ const [currentTreeData, setCurrentTreeData] = useState({
+ key: "",
+ title: "",
+ children: [],
+ });
+
+ const onExpand = (expandedKeysValue: any) => {
+ setExpandedKeys(expandedKeysValue);
+ setAutoExpandParent(false);
+ };
+ const onCheck = (checkedKeysValue: any) => {
+ console.log("onCheck", checkedKeysValue);
+ setCheckedKeys(checkedKeysValue);
+ };
+ const onSelect = (selectedKeysValue: any, info: any) => {
+ console.log("onSelect", info);
+ setSelectedKeys(selectedKeysValue);
+ };
+
+ const onChange = (value: any) => {
+ setCurrent(value);
+ };
+ /**
+ * 加载接口数据
+ */
+ const apiLoad = () => {
+ getApiList().then((res) => {
+ const { data: apiList } = res;
+ setApiTreeList([...apiList]);
+ getApiPermission1(role.id!.toString());
+ });
+ };
+
+ const getApiPermission1 = (id: string) => {
+ getApiPermission(id).then((res) => {
+ const { data: keys } = res;
+ setSelectedKeys(keys);
+ setApiTreeData([...apiTreeList]);
+ // nextTick(() => {
+ // if (apiTreeRef.value) {
+ // apiTreeRef.value.setCheckedKeys(keys, false);
+ // }
+ // });
+ });
+ };
+ /**
+ * 加载菜单数据
+ */
+ const menuLoad = () => {
+ getMenuList().then((res) => {
+ const { data: menuList } = res;
+ const menuTree = listToTree(menuList, 0, {
+ pId: "pId",
+ label: "menuName",
+ });
+ console.log("menuTree", menuTree);
+ setMenuTreeList([...menuTree]);
+ getMenuPermission1(role.id!.toString());
+ });
+ };
+ const getMenuPermission1 = (id: string) => {
+ getMenuPermission(id).then((res) => {
+ const { data: keys } = res;
+ setSelectedKeys(keys);
+ setMenuTreeData([...menuTreeList]);
+ // nextTick(() => {
+ // if (menuTreeRef.value) {
+ // menuTreeRef.value.setCheckedKeys(keys, false);
+ // }
+ // });
+ });
+ };
+ const FirstTree = () => {
+ if (current == 0) {
+ return (
+
+ );
+ } else if (current == 1) {
+ return ;
+ } else if (current == 2) {
+ return 待开发
;
+ }
+ };
+ useEffect(() => {
+ menuLoad();
+ apiLoad();
+ }, []);
+ return (
+ <>
+
+
+
+ {/*
+
+
+
+
+
*/}
+ {/*
待开发
*/}
+
+ >
+ );
};
-export default DialogProgress;
\ No newline at end of file
+export default DialogProgress;
diff --git a/src/views/auth/role/index.tsx b/src/views/auth/role/index.tsx
index abd7e6406e76485557e4885732325fcdf049ff7f..d458b7f44d72ef63584a89bbaa41de7de3ae6611 100644
--- a/src/views/auth/role/index.tsx
+++ b/src/views/auth/role/index.tsx
@@ -1,7 +1,250 @@
+import {
+ addRole,
+ deleteRole,
+ getRoleList,
+ updateRole,
+} from "@/api/system/role";
+import { AppDispatch, RootState } from "@/store";
+import { getPermissionBtns } from "@/store/modules/user";
+import { IRole, IRolePermissionButton } from "@/types";
+import { validatePermission } from "@/utils";
+import {
+ Crud,
+ IActionbar,
+ IColumn,
+ IFormItem,
+ // IPage,
+ IToolbar,
+} from "@ainiteam/quick-react-ui";
+import { ExclamationCircleFilled } from "@ant-design/icons";
+import { Modal, message, Button } from "antd";
+import { useEffect, useState } from "react";
+import { useDispatch, useSelector } from "react-redux";
+import DialogProgress from "./components/DialogProgress";
+
const Role: React.FC = () => {
- return (
- Role
- );
+ /**
+ * 属性
+ */
+ const { confirm } = Modal;
+
+ const [dataList, setDataList] = useState([]);
+ const [loading, setLoading] = useState(false);
+ const dispatch: AppDispatch = useDispatch();
+ const { activeTab } = useSelector((state: RootState) => state.tab);
+ const { permissionBtn }: { permissionBtn: IRolePermissionButton } =
+ useSelector((state: RootState) => state.user);
+ const [dialogVisible, setDialogVisible] = useState(false);
+ const [role, setRole] = useState({});
+ const handleAuth = (item: IRole) => {
+ setDialogVisible(true);
+ setRole({ ...item });
+ };
+
+ /**
+ * 工具栏
+ */
+ const tableToolbar: IToolbar = {
+ hiddenBatchDeleteButton: true,
+ hiddenImportButton: true,
+ hiddenExportButton: true,
+ hiddenPrintButton: true,
+ hiddenAddButton: !validatePermission(permissionBtn?.add),
+ };
+ /**
+ * 操作栏
+ */
+
+ const tableActionbar: IActionbar = {
+ width: 300,
+ hiddenEditButton: true,
+ hiddenDeleteButton: true,
+ hiddenDetailButton: true,
+ btns: [
+ {
+ name: "配置权限",
+ click(item: IRole) {
+ handleAuth(item);
+ },
+ render() {
+ return true;
+ },
+ },
+ ],
+ };
+ /**
+ * 表格
+ */
+ const tableColumns: IColumn[] = [
+ {
+ width: "50",
+ type: "selection",
+ },
+ {
+ label: "角色编号",
+ prop: "roleId",
+ width: "200",
+ },
+ {
+ label: "角色名称",
+ prop: "roleName",
+ },
+ ];
+ const handleDelete = (item: IRole, done: any) => {
+ confirm({
+ title: "警告",
+ icon: ,
+ content: `你真的删除【${item.roleName}】的字典吗?`,
+ onOk() {
+ if (!item.id) {
+ return;
+ }
+ deleteRole(item.id).then(() => {
+ message.success("角色删除成功");
+ done();
+ });
+ },
+ });
+ };
+ /**
+ * 加载数据
+ */
+ const load = () => {
+ setLoading(true);
+ getRoleList().then((res) => {
+ setLoading(false);
+
+ const { data: roleList } = res;
+ setDataList([...roleList]);
+ });
+ };
+ /**
+ * 表单
+ */
+ const dialogTitle = {
+ add: "新增角色",
+ edit: "编辑角色",
+ detail: "角色详情",
+ };
+ const formModel: IRole = {
+ id: undefined,
+ roleId: "",
+ roleName: "",
+ };
+ const formItems: IFormItem[] = [
+ {
+ label: "角色编号",
+ labelWidth: "80px",
+ vModel: "roleId",
+ placeholder: "角色编号",
+ editReadonly: true,
+ prop: "roleId",
+ rules: [
+ {
+ required: true,
+ message: "角色编号不能为空",
+ trigger: "blur",
+ },
+ ],
+ },
+ {
+ label: "角色名称",
+ labelWidth: "80px",
+ vModel: "roleName",
+ placeholder: "角色名称",
+ prop: "roleName",
+ rules: [
+ {
+ required: true,
+ message: "角色名称不能为空",
+ trigger: "blur",
+ },
+ ],
+ },
+ ];
+ const handleFormSubmit = (form: IRole, done: any) => {
+ const row = { ...form };
+ if (row.id) {
+ console.log("updateRole", row);
+ updateRole(row).then(() => {
+ message.success("角色修改成功");
+ done();
+ });
+ } else {
+ row.id = undefined;
+ console.log("addRole", row);
+ addRole(row).then(() => {
+ message.success("角色创建成功");
+ done();
+ });
+ }
+ };
+ /**
+ * 弹窗
+ */
+ const handleOk = () => {
+ setDialogVisible(false);
+ };
+
+ const handleCancel = () => {
+ setDialogVisible(false);
+ };
+ const prev = () => {
+ // dialogProgressRef?.prev();
+ };
+ const next = () => {
+ // dialogProgressRef?.next();
+ };
+ const save = () => {
+ // dialogProgressRef?.save(() => {
+ // setDialogVisible(false);
+ // });
+ };
+ useEffect(() => {
+ dispatch(getPermissionBtns(activeTab));
+ load();
+ }, []);
+
+ return (
+ <>
+
+
+ 上一步
+ ,
+ ,
+ ,
+ ]}
+ >
+
+
+
+
+ >
+ );
};
-export default Role;
\ No newline at end of file
+export default Role;
diff --git a/src/views/help/productIntroduction/index.less b/src/views/help/productIntroduction/index.less
new file mode 100644
index 0000000000000000000000000000000000000000..4ec73eec54b7c59e4d774cf9e927cb976ac868bb
--- /dev/null
+++ b/src/views/help/productIntroduction/index.less
@@ -0,0 +1,30 @@
+.product {
+ .description {
+ font-size: 24px;
+ color: gray;
+ }
+
+ .quick-row {
+ margin-bottom: 15px;
+ }
+
+ .quick-card {
+ height: 400px;
+ }
+ .card4 {
+ margin-right: 15px;
+ }
+ .card2 {
+ margin-right: 15px;
+ }
+ p {
+ font-size: 14px;
+ color: gray;
+ }
+ .quick-button {
+ margin-left: 10px;
+ }
+ .card-header {
+ font-size: 16px;
+ }
+}
diff --git a/src/views/help/productIntroduction/index.tsx b/src/views/help/productIntroduction/index.tsx
index 5d36c997c2b6b02a549d4573ea1732f7a0b7838e..e3e1722e2a8cfed1127e78d4b0be6f504576b25d 100644
--- a/src/views/help/productIntroduction/index.tsx
+++ b/src/views/help/productIntroduction/index.tsx
@@ -1,7 +1,245 @@
+import React from "react";
+import { Button, Card, Col, Row } from "antd";
+import "./index.less";
const ProductIntroduction: React.FC = () => {
- return (
- ProductIntroduction
- );
+ const yanshi = () => {
+ window.open("https://react.quick.ainiteam.com/");
+ };
+ const kaiyuan = () => {
+ window.open("https://gitee.com/zhanglp520/quick-react-admin.git");
+ };
+ return (
+ <>
+
+
+
+
+
+
+ 产品名称:quick中后台开发者系统平台
+
+
+
+ quick-react-admin
+ 是一款免费开源快速搭建中后台系统框架。本框架基于
+ vite5、react、antd、@reduxjs/toolkit 以及 react-router-dom
+ 等最新主流技术并封装了通用的组件方便开发者提高工作效率。后期也会通过版本升级的方式来维护并更新,使开发者拥有一款长期并且稳定的脚手架。本团队还提供了基于
+ quick 框架开发的各类业务项目,比如:
+ 订单管理系统、调度管理系统、聊天系统、音视系统
+ 、监控系统、商城系统、物联网平台、外卖系统、ERP 系统、CMR
+ 系统、OA 系统、物流管理系统、CRM
+ 管理系统等等常用的业务系统,如有相关需求联系管理员。
+
+
+ 开源地址:
+
+
+ 演示地址:
+
+
+ 账号密码:admin/123456
+
+ 如果对你有帮助,帮忙点个star吧!
+ 也可以fork项目并对项目做出贡献!
+
+ 如果想加入项目,请联系管理员!
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1.使用
+ vite5、react8、redux、@reduxjs/toolkit、react-router-dom、antd
+ 和 typescript 等前言技术
+
+ 2.封装了通用的组件
+
+ 3.提供了系统管理常用功能模块
+ 4.提供权限管理模块
+ 5.动态菜单技术
+
+ 6.动态路由技术
+ 7.使用 JWT 鉴权
+
+ 8.使用中间件异常处理
+
+ 9.前后端分离
+
+ 10.后端使用 nestjs 框架
+
+ 11.使用 restful 接口规范
+
+ 12.k8s 分布式
+
+
+
+
+
+ 13.模块化管理
+
+ 14.使用 mvc 架构及多层设计思想
+
+ 15.token 鉴权
+
+ 16.个人资料修改及密码修改功能
+
+ 17.支持支付功能
+
+ 18.docker 容器化
+
+ 19.jenkins 自动化部署技术
+
+ 20.使用 typeorm 框架,可活支持数据库及多种类型的数据库
+
+
+
+
+
+
+
+
+
+
+ 发布版本1.0.1
+
+ 1.菜单优化;
+
+ 2.路由缓存;
+
+ 3.修复bug
+
+
+ 发布版本1.1.0
+
+ 1.增加:资源管理模块
+
+ 2.增加:产品介绍页面
+
+ 3.优化:选项卡
+
+ 4.优化:面包屑
+
+ 5.优化:菜单滚动条;
+
+ 6.修复bug
+
+
+
+
+
+
+
+
+
+
+ 1.开发文档:
+
+
+ 2.接口文档:
+
+
+ 4.码云地址:
+
+
+ 5.github地址:
+
+
+ 6.gitlab地址:
+
+
+ 7.gitee中发起 Issue
+
+ 8.qq群帮助:558795174
+
+
+
+
+
+
+
+
+ 1.承接quick产品的定制化开发
+
+ 2.承接quick产品的业务项目
+
+ 3.组件定制化开发
+
+ 4.其他项目可以联系咨询
+
+ qq:1841031740
+
+
+
+
+
+
+ >
+ );
};
-export default ProductIntroduction;
\ No newline at end of file
+export default ProductIntroduction;
diff --git a/src/views/system/dept/index.tsx b/src/views/system/dept/index.tsx
index 9e8ac460f5bf2eff8a28d3c85bda6a1857b31536..8f189eba4cb34551b3463c4cf65304bce2bffba8 100644
--- a/src/views/system/dept/index.tsx
+++ b/src/views/system/dept/index.tsx
@@ -256,6 +256,7 @@ const Dept: React.FC = () => {
leftTree={leftTree}
leftTreeRefresh={true}
loading={loading}
+ displayNumber={false}
onTreeLoad={treeLoad}
onTreeClick={handleTreeClick}
onFormSubmit={handleFormSubmit}
diff --git a/src/views/system/menu/index.tsx b/src/views/system/menu/index.tsx
index 641a86269e6c4da15e39076679248d01069beef3..d3e0a7d4c698d33b612c0e0afd76e85cf1c8a8be 100644
--- a/src/views/system/menu/index.tsx
+++ b/src/views/system/menu/index.tsx
@@ -164,7 +164,7 @@ const Menu: React.FC = () => {
{
required: true,
message: "请选择菜单类型",
- trigger: "change",
+ // trigger: "change",
},
],
},