From 32f5537af87759313364fd6297f5edc5a8e145aa Mon Sep 17 00:00:00 2001
From: zhangyuanpeng <1016062422@qq.com>
Date: Mon, 25 Nov 2024 17:02:24 +0800
Subject: [PATCH 1/4] =?UTF-8?q?feat:=20:sparkles:=20=E5=BC=95=E5=85=A5da-t?=
=?UTF-8?q?ree=E6=A0=91=E7=BB=84=E4=BB=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/components/da-tree/changelog.md | 196 +++++
src/components/da-tree/index.vue | 1206 +++++++++++++++++++++++++++
src/components/da-tree/props.ts | 197 +++++
src/components/da-tree/readme.md | 310 +++++++
src/components/da-tree/utils.ts | 150 ++++
5 files changed, 2059 insertions(+)
create mode 100644 src/components/da-tree/changelog.md
create mode 100644 src/components/da-tree/index.vue
create mode 100644 src/components/da-tree/props.ts
create mode 100644 src/components/da-tree/readme.md
create mode 100644 src/components/da-tree/utils.ts
diff --git a/src/components/da-tree/changelog.md b/src/components/da-tree/changelog.md
new file mode 100644
index 0000000..7117197
--- /dev/null
+++ b/src/components/da-tree/changelog.md
@@ -0,0 +1,196 @@
+# 1.4.2
+
+新增
+
+1. 新增`filterValue`属性,支持通过此关键词来搜索并筛选树结构的内容
+
+# 1.4.1
+
+修复
+
+1. 修复单选 onlyRadioLeaf 时末级节点无法选中的 bug
+
+# 1.4.0
+
+版本调整
+
+建议更新,但需要注意,异步数据的时候,后台需返回 leaf 字段来判断是否末项数据
+
+1. **调整数据项格式,新增 `leaf` 字段,来判断是否为末节点**
+2. **调整数据项格式,新增 `sort` 字段,来排序节点位置**
+3. **注意:异步加载数据,当为末项的时候,需要服务端数据返回 `leaf` 字段**
+4. 新增 `alwaysFirstLoad` ,即异步数据总会在第一次展开节点时,拉取一次后台数据,来比对是否一致
+5. 拆分 `field` 属性,**注意: 1.5.0 版本后将移除 `field` 属性**
+6. 新增 `labelField` 同 `field.label`,指定节点对象中某个属性为**标签**字段,默认`label`
+7. 新增 `valueField` 同 `field.key`,指定节点对象中某个属性为**值**字段,默认`value`
+8. 新增 `childrenField` 同 `field.children`,指定节点对象中某个属性为**子树节点**字段,默认`children`
+9. 新增 `disabledField` 同 `field.disabled`,指定节点对象中某个属性为**禁用**字段,默认`disabled`
+10. 新增 `appendField` 同 `field.append`,指定节点对象中某个属性为**副标签**字段,默认`append`
+11. 新增 `leafField` 同 `field.label`,指定节点对象中某个属性为**末级节点**字段,默认`leaf`
+12. 新增 `sortField` 同 `field.label`,指定节点对象中某个属性为**排序**字段,默认`sort`
+13. 新增 `isLeafFn` ,用来自定义控制数据项的末项
+14. 更多的项目示例
+15. 支持单选取消选中
+16. 修复节点展开时可能存在的 bug
+17. 修复节点选择可能存在的 bug
+18. 调整为子节点默认继承父节点禁用属性
+19. `setExpandedKeys` 添加参数一为 `all` 即可支持一键展开/收起全部节点
+20. 其它更多优化
+
+# 1.3.4
+
+优化
+
+1. 优化图标字体命名
+
+# 1.3.3
+
+优化
+
+1. 新增方法调用
+ > - 新增`getUncheckedKeys`,返回未选的 key
+ > - 新增`getUncheckedNodes`,返回未选的节点
+ > - 新增`getUnexpandedKeys`,返回未展开的 key
+ > - 新增`getUnexpandedNodes`,返回未展开的节点
+2. 优化示例项目
+
+# 1.3.2
+
+修复
+
+1. 修复在 APP 真机环境中的报错
+
+# 1.3.1
+
+修复
+
+1. 修复方法`setExpandedKeys`没联动展开上级父子节点
+
+# 1.3.0
+
+优化
+
+1. `field`新增字段 `append` 用于在标签后面显示小提示
+2. 新增支持点击标签也能选中节点
+3. 方法`setExpandedKeys`支持加载动态数据
+4. 修复父节点禁用,则不能展开及图标展开显示
+5. 修复动态加载数据时,末级节点的 `children` 为 `null` 时仍显示展开图标
+
+# 1.2.6
+
+新增
+
+1. 新增支持主题换色
+2. 支持单选的`onlyRadioLeaf`为`true`时可点父节点展开/收起
+3. 优化`expandChecked`调整为不展开无子节点的节点
+
+# 1.2.5
+
+新增
+
+1. 新增 `expandChecked`,控制选择时是否展开当前已选的所有下级节点
+
+# 1.2.4
+
+修复
+
+1. 修复动态数据展开状态异常问题
+
+# 1.2.3
+
+新增
+
+1. 新增 `checkedDisabled`,是否渲染禁用值
+2. 新增 `packDisabledkey`,是否返回已禁用并选中的 key
+3. 修复选择父级时,子级已禁用但仍被选中的问题
+
+# 1.2.2
+
+优化
+
+1. 调整动态数据载入处理方式
+2. 修复节点数据因动态数据引起的状态异常
+3. 修复初始节点数据默认选中
+
+# 1.2.1
+
+修复
+
+1. 修复切换`选中状态`被重复选中问题
+2. 修复动态数据引起的重复选择问题
+
+# 1.2.0
+
+新增
+
+1. 新增方法调用
+ > - 新增`setCheckedKeys`,方法设置指定 key 的节点选中状态
+ > - 新增`setExpandedKeys`,方法设置指定 key 的节点展开状态
+2. 修复小程序重复插槽一直刷报错问题
+3. 优化展开时,会展开子级所以下级节点
+
+# 1.1.1
+
+新增
+
+1. 新增`data`的`disabled`,支持节点禁用状态
+2. 新增`field`的`disabled`,可自定`disabled`字段值
+
+# 1.1.0
+
+新增
+
+1. 新增`loadMode`、`loadApi`,支持展开时加载异步数据
+2. 新增方法调用
+ > - 新增`getCheckedKeys`,方法返回已选的 key
+ > - 新增`getHalfCheckedKeys`,方法返回半选的 key
+ > - 新增`getExpandedKeys`,方法返回已展开的 key
+ > - 新增`getCheckedNodes`,方法返回已选的节点
+ > - 新增`getHalfCheckedNodes`,方法返回半选的节点
+ > - 新增`getExpandedNodes`,方法返回已展开的节点
+3. 对代码进行重构,更易于后期拓展
+4. 此次更新后,页面多个的 DaTee 组件间的数据不再关联
+
+# 1.0.6
+
+新增
+
+1. 新增`checkStrictly`,多选模式下选中时是否父子不关联
+
+# 1.0.5
+
+修复
+
+1. 修复多选时已选数据重复问题
+
+# 1.0.4
+
+修复
+
+1. 修复 `change` 事件回调数据的问题
+
+# 1.0.3
+
+优化
+
+1. 优化文档及示例说明
+
+# 1.0.2
+
+新增
+
+1. 新增 `onlyRadioLeaf` ,单选时只允许选中末级
+2. 优化默认展开及默认选择的展开问题
+
+# 1.0.1
+
+新增
+
+1. 支持展开/收起回调事件`@expand`
+
+# 1.0.0
+
+初始版本 1.0.0,基于 Vue3 进行开发,支持单选、多选,兼容各大平台
+
+1. 支持单选
+2. 支持多选
diff --git a/src/components/da-tree/index.vue b/src/components/da-tree/index.vue
new file mode 100644
index 0000000..03b0329
--- /dev/null
+++ b/src/components/da-tree/index.vue
@@ -0,0 +1,1206 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.label }}
+ {{ item.append }}
+
+
+
+
+
+
+
+
+
diff --git a/src/components/da-tree/props.ts b/src/components/da-tree/props.ts
new file mode 100644
index 0000000..4b710df
--- /dev/null
+++ b/src/components/da-tree/props.ts
@@ -0,0 +1,197 @@
+export default {
+ /**
+ * 树的数据
+ */
+ data: {
+ type: Array,
+ default: () => [],
+ },
+ /**
+ * 主题色
+ */
+ themeColor: {
+ type: String,
+ default: "#007aff",
+ },
+ /**
+ * 是否开启多选,默认单选
+ */
+ showCheckbox: {
+ type: Boolean,
+ default: false,
+ },
+ /**
+ * 默认选中的节点,注意单选时为单个key,多选时为key的数组
+ */
+ defaultCheckedKeys: {
+ type: [Array, String, Number],
+ default: null,
+ },
+ /**
+ * 是否默认展开全部
+ */
+ defaultExpandAll: {
+ type: Boolean,
+ default: false,
+ },
+ /**
+ * 默认展开的节点
+ */
+ defaultExpandedKeys: {
+ type: Array,
+ default: null,
+ },
+ /**
+ * 筛选关键词
+ */
+ filterValue: {
+ type: String,
+ default: "",
+ },
+ /**
+ * 是否自动展开到选中的节点,默认不展开
+ */
+ expandChecked: {
+ type: Boolean,
+ default: false,
+ },
+
+ /**
+ * (旧)字段对应内容,默认为 {label: 'label',key: 'key', children: 'children', disabled: 'disabled', append: 'append'}
+ * 注意:1.5.0版本后不再兼容
+ */
+ field: {
+ type: Object,
+ default: null,
+ },
+ /**
+ * 标签字段(新,拆分了)
+ */
+ labelField: {
+ type: String,
+ default: "label",
+ },
+ /**
+ * 值字段(新,拆分了)
+ */
+ valueField: {
+ type: String,
+ default: "value",
+ },
+ /**
+ * 下级字段(新,拆分了)
+ */
+ childrenField: {
+ type: String,
+ default: "children",
+ },
+ /**
+ * 禁用字段(新,拆分了)
+ */
+ disabledField: {
+ type: String,
+ default: "disabled",
+ },
+ /**
+ * 末级节点字段(新,拆分了)
+ */
+ leafField: {
+ type: String,
+ default: "leaf",
+ },
+ /**
+ * 副标签字段(新,拆分了)
+ */
+ appendField: {
+ type: String,
+ default: "append",
+ },
+ /**
+ * 排序字段(新,拆分了)
+ */
+ sortField: {
+ type: String,
+ default: "sort",
+ },
+ /**
+ * Api数据返回后的结果路径,支持嵌套如`data.list`
+ */
+ resultField: {
+ type: String,
+ default: "",
+ },
+ isLeafFn: {
+ type: Function,
+ default: null,
+ },
+ /**
+ * 是否显示单选图标,默认显示
+ */
+ showRadioIcon: {
+ type: Boolean,
+ default: true,
+ },
+ /**
+ * 单选时只允许选中末级,默认可随意选中
+ */
+ onlyRadioLeaf: {
+ type: Boolean,
+ default: false,
+ },
+ /**
+ * 多选时,是否执行父子不关联的任意勾选,默认父子关联
+ */
+ checkStrictly: {
+ type: Boolean,
+ default: false,
+ },
+ /**
+ * 为 true 时,空的 children 数组会显示展开图标
+ */
+ loadMode: {
+ type: Boolean,
+ default: false,
+ },
+ /**
+ * 异步加载接口
+ */
+ loadApi: {
+ type: Function,
+ default: null,
+ },
+ /**
+ * 是否总在首次的时候加载一下内容,来比对是否一致
+ */
+ alwaysFirstLoad: {
+ type: Boolean,
+ default: false,
+ },
+ /**
+ * 是否渲染(操作)禁用值
+ */
+ checkedDisabled: {
+ type: Boolean,
+ default: false,
+ },
+ /**
+ * 是否返回已禁用的但已选中的key
+ */
+ packDisabledkey: {
+ type: Boolean,
+ default: true,
+ },
+ /**
+ * 选择框的位置,可选 left/right
+ */
+ checkboxPlacement: {
+ type: String,
+ default: "left",
+ },
+ /**
+ * 子项缩进距离,默认40,单位rpx
+ */
+ indent: {
+ type: Number,
+ default: 40,
+ },
+};
diff --git a/src/components/da-tree/readme.md b/src/components/da-tree/readme.md
new file mode 100644
index 0000000..fa3f318
--- /dev/null
+++ b/src/components/da-tree/readme.md
@@ -0,0 +1,310 @@
+# da-tree
+
+一个基于 Vue3 的 tree(树)组件,同时支持主题换色,可能是最适合你的 tree(树)组件
+
+组件一直在更新,遇到问题可在下方讨论。
+
+`同时更新 Vue2 版本,在此查看 ===>` **[Vue2 版](https://ext.dcloud.net.cn/plugin?id=12692)**
+
+### 关于使用
+
+可在右侧的`使用 HBuilderX 导入插件`或`下载示例项目ZIP`,方便快速上手。
+
+可通过下方的示例及文档说明,进一步了解使用组件相关细节参数。
+
+插件地址:https://ext.dcloud.net.cn/plugin?id=12384
+
+### 组件示例
+
+```jsx
+
+ 多选
+
+
+
+
+
+
+
+
+
+ 单选
+
+ 默认展开指定节点
+
+ 异步加载数据
+
+
+```
+
+```js
+import { defineComponent, ref } from "vue";
+
+/**
+ * 模拟创建一个接口数据
+ */
+function GetApiData(currentNode) {
+ const { key } = currentNode;
+
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ // 模拟返回空数据
+ if (key.indexOf("-") > -1) {
+ return resolve(null);
+ // return resolve([])
+ }
+
+ return resolve([
+ {
+ id: `${key}-1`,
+ name: `行政部X${key}-1`,
+ },
+ {
+ id: `${key}-2`,
+ name: `财务部X${key}-2`,
+ append: "定义了末项数据",
+ leaf: true,
+ },
+ {
+ id: `${key}-3`,
+ name: `资源部X${key}-3`,
+ },
+ {
+ id: `${key}-4`,
+ name: `资源部X${key}-3`,
+ append: "被禁用,无展开图标",
+ disabled: true,
+ },
+ ]);
+ }, 2000);
+ });
+}
+
+import DaTree from "@/components/da-tree/index.vue";
+export default defineComponent({
+ components: { DaTree },
+ setup() {
+ const DaTreeRef = ref();
+ // key的类型必须对应树数据key的类型
+ const defaultCheckedKeysValue = ref(["211", "222"]);
+ const defaultCheckedKeysValue2 = ref("222");
+ const defaultExpandKeysValue3 = ref(["212", "231"]);
+ const roomTreeData = ref([
+ {
+ id: "2",
+ name: "行政中心",
+ children: [
+ {
+ id: "21",
+ name: "行政部",
+ children: [
+ {
+ id: "211",
+ name: "行政一部",
+ children: null,
+ },
+ {
+ id: "212",
+ name: "行政二部",
+ children: [],
+ disabled: true,
+ },
+ ],
+ },
+ {
+ id: "22",
+ name: "财务部",
+ children: [
+ {
+ id: "221",
+ name: "财务一部",
+ children: [],
+ disabled: true,
+ },
+ {
+ id: "222",
+ name: "财务二部",
+ children: [],
+ },
+ ],
+ },
+ {
+ id: "23",
+ name: "人力资源部",
+ children: [
+ {
+ id: "231",
+ name: "人力一部",
+ children: [],
+ },
+ {
+ id: "232",
+ name: "人力二部",
+ append: "更多示例,请下载示例项目查看",
+ },
+ ],
+ },
+ ],
+ },
+ ]);
+ function doExpandTree(keys, expand) {
+ DaTreeRef.value?.setExpandedKeys(keys, expand);
+
+ const gek = DaTreeRef.value?.getExpandedKeys();
+ console.log("当前已展开的KEY ==>", gek);
+ }
+ function doCheckedTree(keys, checked) {
+ DaTreeRef.value?.setCheckedKeys(keys, checked);
+
+ const gek = DaTreeRef.value?.getCheckedKeys();
+ console.log("当前已选中的KEY ==>", gek);
+ }
+ function handleTreeChange(allSelectedKeys, currentItem) {
+ console.log("handleTreeChange ==>", allSelectedKeys, currentItem);
+ }
+ function handleExpandChange(expand, currentItem) {
+ console.log("handleExpandChange ==>", expand, currentItem);
+ }
+ return {
+ DaTreeRef,
+ roomTreeData,
+ defaultCheckedKeysValue,
+ defaultCheckedKeysValue2,
+ defaultExpandKeysValue3,
+ handleTreeChange,
+ handleExpandChange,
+ GetApiData,
+ doExpandTree,
+ doCheckedTree,
+ };
+ },
+});
+```
+
+** 更多示例请下载/导入示例项目 ZIP 查看 **
+
+### 组件参数
+
+| 属性 | 类型 | 默认值 | 必填 | 说明 |
+| :------------------ | :------------------------------ | :--------- | :--- | :--------------------------------------------------------------------------- |
+| data | `Array` | - | 是 | 树的数据 |
+| themeColor | `String` | `#007aff` | 否 | 主题色,十六进制 |
+| defaultCheckedKeys | `Array` \| `Number` \| `String` | - | 否 | 默认选中的节点,单选为单个 key,多选为 key 的数组 |
+| showCheckbox | `Boolean` | `false` | 否 | 是否开启多选,默认单选 |
+| checkStrictly | `Boolean` | `false` | 否 | 多选时,是否执行父子不关联的任意勾选,默认父子关联 |
+| showRadioIcon | `Boolean` | `true` | 否 | 是否显示单选图标,默认显示 |
+| onlyRadioLeaf | `Boolean` | `true` | 否 | 单选时只允许选中末级,默认可随意选中 |
+| defaultExpandAll | `Boolean` | `false` | 否 | 是否默认展开全部 |
+| defaultExpandedKeys | `Array` | - | 否 | 默认展开的节点 |
+| indent | `Number` | `40` | 否 | 子项缩进距离,单位 rpx |
+| checkboxPlacement | `String` | `left` | 否 | 选择框的位置,可选 left/right |
+| loadMode | `Boolean` | `false` | 否 | 为 true 时,空的 children 数组会显示展开图标 |
+| loadApi | `Function` | - | 否 | 选择框的位置,可选 left/right |
+| checkedDisabled | `Boolean` | `false` | 否 | 是否渲染禁用值,默认不渲染 |
+| packDisabledkey | `Boolean` | `true` | 否 | 是否返回已禁用的但已选中的 key,默认返回禁用已选值 |
+| expandChecked | `Boolean` | `false` | 否 | 是否自动展开到选中的节点,默认不展开 |
+| alwaysFirstLoad | `Boolean` | `false` | 否 | 是否总在首次的时候加载一下内容,默认不加载,否则只有展开末级节点才会加载数据 |
+| isLeafFn | `Function` | - | 否 | 自定义函数返回来控制数据项的末项 |
+| field | `Object` | - | 否 | 字段对应内容,格式参考下方(1.5.0 后移除,请用单独的字段匹配) |
+| labelField | `String` | `label` | 否 | 指定节点对象中某个属性为标签字段,默认`label` |
+| valueField | `String` | `value` | 否 | 指定节点对象中某个属性为值字段,默认`value` |
+| childrenField | `String` | `children` | 否 | 指定节点对象中某个属性为子树节点字段,默认`children` |
+| disabledField | `String` | `disabled` | 否 | 指定节点对象中某个属性为禁用字段,默认`disabled` |
+| appendField | `String` | `append` | 否 | 指定节点对象中某个属性为副标签字段,默认`append` |
+| leafField | `String` | `leaf` | 否 | 指定节点对象中某个属性为末级节点字段,默认`leaf` |
+| sortField | `String` | `sort` | 否 | 指定节点对象中某个属性为排序字段,默认`sort` |
+| filterValue | `String` | - | 否 | 搜索筛选的关键词,通过输入关键词筛选内容 |
+
+**field 格式(1.5.0 后移除,请用单独的字段匹配)**
+
+```js
+{
+ label: 'label',
+ key: 'key',
+ children: 'children',
+ disabled: 'disabled',
+ append: 'append'
+}
+```
+
+### 组件事件
+
+| 事件名称 | 回调参数 | 说明 |
+| :------- | :-------------------------------------- | :-------------- |
+| change | `(allCheckedKeys, currentItem) => void` | 选中时回调 |
+| expand | `(expandState, currentItem) => void` | 展开/收起时回调 |
+
+### 组件方法
+
+| 方法名称 | 参数 | 说明 |
+| :------------------ | :--------------- | :------------------------------------------------------------------------------------------------ |
+| setCheckedKeys | `(keys,checked)` | 设置指定 key 的节点选中/取消选中的状态。注: keys 单选时为 key,多选时为 key 的数组 |
+| setExpandedKeys | `(keys,expand)` | 设置指定 key 的节点展开/收起的状态,当 keys 为 all 时即代表展开/收起全部。注:keys 为数组或 `all` |
+| getCheckedKeys | - | 返回已选的 key |
+| getHalfCheckedKeys | - | 返回半选的 key |
+| getUncheckedKeys | - | 返回未选的 key |
+| getCheckedNodes | - | 返回已选的节点 |
+| getUncheckedNodes | - | 返回未选的节点 |
+| getHalfCheckedNodes | - | 返回半选的节点 |
+| getExpandedKeys | - | 返回已展开的 key |
+| getUnexpandedKeys | - | 返回未展开的 key |
+| getExpandedNodes | - | 返回已展开的节点 |
+| getUnexpandedNodes | - | 返回未展开的节点 |
+
+### 组件版本
+
+v1.4.2
+
+### 差异化
+
+已通过测试
+
+> - H5 页面
+> - 微信小程序
+> - 支付宝、钉钉小程序
+> - 字节跳动、抖音、今日头条小程序
+> - 百度小程序
+> - 飞书小程序
+> - QQ 小程序
+> - 京东小程序
+
+未测试
+
+> - 快手小程序由于非企业用户暂无演示
+> - 快应用、360 小程序因 Vue3 支持的原因暂无演示
+
+### 开发组
+
+[@CRLANG](https://crlang.com)
diff --git a/src/components/da-tree/utils.ts b/src/components/da-tree/utils.ts
new file mode 100644
index 0000000..d79ea1e
--- /dev/null
+++ b/src/components/da-tree/utils.ts
@@ -0,0 +1,150 @@
+/** 未选 */
+export const unCheckedStatus = 0;
+/** 半选 */
+export const halfCheckedStatus = 1;
+/** 选中 */
+export const isCheckedStatus = 2;
+
+/**
+ * 深拷贝内容
+ * @param originData 拷贝对象
+ * @author crlang(https://crlang.com)
+ */
+export function deepClone(originData) {
+ const type = Object.prototype.toString.call(originData);
+ let data;
+ if (type === "[object Array]") {
+ data = [];
+ for (let i = 0; i < originData.length; i++) {
+ data.push(deepClone(originData[i]));
+ }
+ } else if (type === "[object Object]") {
+ data = {};
+ for (const prop in originData) {
+ if (originData.hasOwnProperty(prop)) {
+ // 非继承属性
+ data[prop] = deepClone(originData[prop]);
+ }
+ }
+ } else {
+ data = originData;
+ }
+ return data;
+}
+
+/**
+ * 获取所有指定的节点
+ * @param type
+ * @param value
+ * @author crlang(https://crlang.com)
+ */
+export function getAllNodes(list, type, value, packDisabledkey = true) {
+ if (!list || list.length === 0) {
+ return [];
+ }
+
+ const res = [];
+ for (let i = 0; i < list.length; i++) {
+ const item = list[i];
+ if (item[type] === value) {
+ if ((packDisabledkey && item.disabled) || !item.disabled) {
+ res.push(item);
+ }
+ }
+ }
+
+ return res;
+}
+
+/**
+ * 获取所有指定的key值
+ * @param type
+ * @param value
+ * @author crlang(https://crlang.com)
+ */
+export function getAllNodeKeys(list, type, value, packDisabledkey = true) {
+ if (!list || list.length === 0) {
+ return null;
+ }
+
+ const res = [];
+ for (let i = 0; i < list.length; i++) {
+ const item = list[i];
+ if (item[type] === value) {
+ if ((packDisabledkey && item.disabled) || !item.disabled) {
+ res.push(item.key);
+ }
+ }
+ }
+
+ return res.length ? res : null;
+}
+
+/**
+ * 错误输出
+ *
+ * @param msg
+ */
+export function logError(msg, ...args) {
+ console.error(`DaTree: ${msg}`, ...args);
+}
+
+const toString = Object.prototype.toString;
+
+export function is(val, type) {
+ return toString.call(val) === `[object ${type}]`;
+}
+
+/**
+ * 是否对象(Object)
+ * @param val
+
+ */
+export function isObject(val) {
+ return val !== null && is(val, "Object");
+}
+
+/**
+ * 是否数字(Number)
+ * @param val
+
+ */
+export function isNumber(val) {
+ return is(val, "Number");
+}
+
+/**
+ * 是否字符串(String)
+ * @param val
+
+ */
+export function isString(val) {
+ return is(val, "String");
+}
+
+/**
+ * 是否函数方法(Function)
+ * @param val
+
+ */
+export function isFunction(val) {
+ return typeof val === "function";
+}
+
+/**
+ * 是否布尔(Boolean)
+ * @param val
+
+ */
+export function isBoolean(val) {
+ return is(val, "Boolean");
+}
+
+/**
+ * 是否数组(Array)
+ * @param val
+
+ */
+export function isArray(val) {
+ return val && Array.isArray(val);
+}
From e240f4acc8b7150f950320a21cf157facd4d4340 Mon Sep 17 00:00:00 2001
From: zhangyuanpeng <1016062422@qq.com>
Date: Mon, 25 Nov 2024 17:08:39 +0800
Subject: [PATCH 2/4] =?UTF-8?q?feat:=20:sparkles:=20=E8=A7=92=E8=89=B2?=
=?UTF-8?q?=E7=AE=A1=E7=90=86?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/api/system/menu.ts | 76 +++++++
src/pages.json | 12 ++
src/pages/work/index.vue | 1 +
src/pages/work/role/assign-perm.vue | 113 ++++++++++
src/pages/work/role/index.vue | 319 ++++++++++++++++++++++++++++
5 files changed, 521 insertions(+)
create mode 100644 src/api/system/menu.ts
create mode 100644 src/pages/work/role/assign-perm.vue
create mode 100644 src/pages/work/role/index.vue
diff --git a/src/api/system/menu.ts b/src/api/system/menu.ts
new file mode 100644
index 0000000..54424c2
--- /dev/null
+++ b/src/api/system/menu.ts
@@ -0,0 +1,76 @@
+import request from "@/utils/request";
+// 菜单基础URL
+const MENU_BASE_URL = "/api/v1/menus";
+
+const MenuAPI = {
+ /**
+ * 获取当前用户的路由列表
+ *
+ * 无需传入角色,后端解析token获取角色自行判断是否拥有路由的权限
+ *
+ * @returns 路由列表
+ */
+ getRoutes() {
+ return request({
+ url: `${MENU_BASE_URL}/routes`,
+ method: "GET",
+ });
+ },
+
+ /**
+ * 获取菜单下拉数据源
+ *
+ * @returns 菜单下拉数据源
+ */
+ getOptions(onlyParent?: boolean) {
+ return request({
+ url: `${MENU_BASE_URL}/options`,
+ method: "GET",
+ data: { onlyParent: onlyParent },
+ });
+ },
+};
+
+export default MenuAPI;
+
+/** RouteVO,路由对象 */
+export interface RouteVO {
+ /** 子路由列表 */
+ children: RouteVO[];
+ /** 组件路径 */
+ component?: string;
+ /** 路由属性 */
+ meta?: Meta;
+ /** 路由名称 */
+ name?: string;
+ /** 路由路径 */
+ path?: string;
+ /** 跳转链接 */
+ redirect?: string;
+}
+
+/** Meta,路由属性 */
+export interface Meta {
+ /** 【目录】只有一个子路由是否始终显示 */
+ alwaysShow?: boolean;
+ /** 是否隐藏(true-是 false-否) */
+ hidden?: boolean;
+ /** ICON */
+ icon?: string;
+ /** 【菜单】是否开启页面缓存 */
+ keepAlive?: boolean;
+ /** 路由title */
+ title?: string;
+}
+
+/**
+ * 组件数据源
+ */
+interface OptionType {
+ /** 值 */
+ value: string | number;
+ /** 文本 */
+ label: string;
+ /** 子列表 */
+ children?: OptionType[];
+}
diff --git a/src/pages.json b/src/pages.json
index 37a4746..e7afde2 100644
--- a/src/pages.json
+++ b/src/pages.json
@@ -67,6 +67,18 @@
"style": {
"navigationBarTitleText": "通知详情"
}
+ },
+ {
+ "path": "pages/work/role/index",
+ "style": {
+ "navigationBarTitleText": "角色管理"
+ }
+ },
+ {
+ "path": "pages/work/role/assign-perm",
+ "style": {
+ "navigationBarTitleText": "角色分配权限"
+ }
}
],
"globalStyle": {
diff --git a/src/pages/work/index.vue b/src/pages/work/index.vue
index cd6dd54..62c6da3 100644
--- a/src/pages/work/index.vue
+++ b/src/pages/work/index.vue
@@ -36,6 +36,7 @@ const gridList = reactive([
{
icon: "/static/icons/role.png",
title: "角色管理",
+ url: "/pages/work/role/index",
prem: "sys:role:query",
},
{
diff --git a/src/pages/work/role/assign-perm.vue b/src/pages/work/role/assign-perm.vue
new file mode 100644
index 0000000..0cb2843
--- /dev/null
+++ b/src/pages/work/role/assign-perm.vue
@@ -0,0 +1,113 @@
+
+
+
+
+
+
+
+ 全 选
+
+
+ 全不选
+
+
+ 全展开
+
+
+ 全收起
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/work/role/index.vue b/src/pages/work/role/index.vue
new file mode 100644
index 0000000..1044cc0
--- /dev/null
+++ b/src/pages/work/role/index.vue
@@ -0,0 +1,319 @@
+
+
+
+
+
+
+
+
+ 重置
+ 确定
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.name }}
+
+
+
+
+ 正常
+ 停用
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
From 024740ab11e7a7f255a33352dd233b147e262ead Mon Sep 17 00:00:00 2001
From: zhangyuanpeng <1016062422@qq.com>
Date: Mon, 25 Nov 2024 17:26:14 +0800
Subject: [PATCH 3/4] =?UTF-8?q?refactor:=20:recycle:=20=E4=B8=AA=E4=BA=BA?=
=?UTF-8?q?=E4=B8=AD=E5=BF=83=E6=A0=B7=E5=BC=8F=E4=BC=98=E5=8C=96-px?=
=?UTF-8?q?=E6=94=B9=E4=B8=BArpx?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/pages/mine/profile/index.vue | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/src/pages/mine/profile/index.vue b/src/pages/mine/profile/index.vue
index a44bdf4..976edac 100644
--- a/src/pages/mine/profile/index.vue
+++ b/src/pages/mine/profile/index.vue
@@ -66,7 +66,7 @@
-
+
-
+
男
女
@@ -103,7 +103,7 @@
From 49be295caa034b9bcc763dcdcae4af378bb473d0 Mon Sep 17 00:00:00 2001
From: zhangyuanpeng <1016062422@qq.com>
Date: Mon, 25 Nov 2024 18:41:44 +0800
Subject: [PATCH 4/4] =?UTF-8?q?refactor:=20:recycle:=20=E6=93=8D=E4=BD=9C?=
=?UTF-8?q?=E6=8C=89=E9=92=AE=E7=94=B1=E5=9B=BE=E6=A0=87=E6=94=B9=E4=B8=BA?=
=?UTF-8?q?=E6=96=87=E5=AD=97?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/pages/work/role/index.vue | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/pages/work/role/index.vue b/src/pages/work/role/index.vue
index 1044cc0..b7823e9 100644
--- a/src/pages/work/role/index.vue
+++ b/src/pages/work/role/index.vue
@@ -48,7 +48,7 @@
-
+ 操作