Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
R
rsbuild-vue3-template
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
曾哲
rsbuild-vue3-template
Commits
a9ae07d6
提交
a9ae07d6
authored
12月 09, 2024
作者:
xiejiang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix: 修复菜单,等测试出的bug
上级
503f411b
显示空白字符变更
内嵌
并排
正在显示
32 个修改的文件
包含
441 行增加
和
245 行删除
+441
-245
index.ts
src/api/interface/menu/index.ts
+2
-2
index.ts
src/api/interface/version/index.ts
+2
-2
index.vue
src/components/PageContainer/index.vue
+13
-2
index.vue
src/components/PageFilters/index.vue
+29
-12
index.ts
src/components/PageFilters/interface/index.ts
+9
-0
index.vue
src/components/SearchWithButton/index.vue
+5
-4
index.vue
src/components/WangEditor/index.vue
+8
-0
index.ts
src/routers/index.ts
+3
-0
detail.vue
src/views/customer/institution/detail.vue
+22
-5
edit.vue
src/views/customer/institution/edit.vue
+10
-5
index.vue
src/views/customer/institution/index.vue
+23
-4
index.vue
src/views/login/index.vue
+2
-1
dictionary-subset.vue
src/views/sys-config/dictionary/dictionary-subset.vue
+5
-10
index.vue
src/views/sys-config/dictionary/index.vue
+15
-8
dictionary-edit.vue
src/views/sys-config/dictionary/page/dictionary-edit.vue
+1
-5
dictionary-subset-edit.vue
...ews/sys-config/dictionary/page/dictionary-subset-edit.vue
+2
-8
index.vue
src/views/sys-config/menu/index.vue
+15
-3
menu-edit.vue
src/views/sys-config/menu/page/menu-edit.vue
+1
-5
menu-log.vue
src/views/sys-config/menu/page/menu-log.vue
+1
-6
menu-sort.vue
src/views/sys-config/menu/page/menu-sort.vue
+2
-2
index.vue
src/views/sys-config/version/index.vue
+15
-4
version-detail.vue
src/views/sys-config/version/page/version-detail.vue
+9
-1
version-edit.vue
src/views/sys-config/version/page/version-edit.vue
+5
-5
index.vue
src/views/sys-permissions/authority/index.vue
+10
-10
capabilities.vue
src/views/sys-permissions/authority/page/capabilities.vue
+5
-9
copy-permissions.vue
...views/sys-permissions/authority/page/copy-permissions.vue
+46
-36
data-permissions.vue
...views/sys-permissions/authority/page/data-permissions.vue
+43
-19
index.vue
src/views/sys-permissions/role/index.vue
+14
-5
role-edit.vue
src/views/sys-permissions/role/page/role-edit.vue
+1
-7
detail.vue
src/views/sys-permissions/user/detail.vue
+84
-45
index.vue
src/views/sys-permissions/user/index.vue
+30
-8
user-edit.vue
src/views/sys-permissions/user/page/user-edit.vue
+9
-12
没有找到文件。
src/api/interface/menu/index.ts
浏览文件 @
a9ae07d6
...
...
@@ -2,7 +2,7 @@
* @Author: xiejiang
* @Date: 2024-12-03 10:43:24
* @LastEditors: xiejiang
* @LastEditTime: 2024-12-0
6 15:22:47
* @LastEditTime: 2024-12-0
9 09:54:16
* @Description:
* Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved.
*/
...
...
@@ -24,7 +24,7 @@ export interface ResMenu extends KeyAny {
inputTime
?:
string
//创建时间
inputUserId
?:
number
//创建人ID
inputUserName
?:
string
//创建人姓名
menuId
?:
number
|
string
//菜单编号
menuId
?:
string
//菜单编号
menuLevel
:
number
|
string
//菜单层级
menuName
:
string
//菜单名称
menuSign
:
string
//菜单标识(路由名称)
...
...
src/api/interface/version/index.ts
浏览文件 @
a9ae07d6
...
...
@@ -2,7 +2,7 @@
* @Author: xiejiang
* @Date: 2024-12-05 09:20:12
* @LastEditors: xiejiang
* @LastEditTime: 2024-12-0
5 15:07:43
* @LastEditTime: 2024-12-0
9 17:52:26
* @Description:
* Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved.
*/
...
...
@@ -47,6 +47,6 @@ export interface ResVersionPage {
publishedNum
:
number
// 已发布数量 [必填]
pageInfo
:
{
list
:
ResVersion
[]
}
total
:
number
// 总数 [必填]
}
}
src/components/PageContainer/index.vue
浏览文件 @
a9ae07d6
...
...
@@ -2,13 +2,18 @@
* @Author: xiejiang
* @Date: 2024-11-07 11:19:31
* @LastEditors: xiejiang
* @LastEditTime: 2024-12-0
5 09:27:39
* @LastEditTime: 2024-12-0
9 12:00:01
* @Description: 表格页面容器组件
-->
<
template
>
<div
class=
"h-full flex flex-col"
>
<!-- 筛选区域 -->
<PageFilters
:filter-conditions=
"props.filterConditions"
v-bind=
"filtersProps"
@
on-filter=
"handleSeach"
/>
<PageFilters
:filter-conditions=
"props.filterConditions"
v-bind=
"filtersProps"
@
on-filter=
"handleSeach"
@
clear=
"handleClear"
/>
<div
class=
"mt-[12px] p-[16px] bg-white flex-1 max-h-[calc(100%-64px)] overflow-auto"
>
<!-- 表格头部操作区 -->
<div
class=
"flex justify-between items-center"
>
...
...
@@ -108,9 +113,15 @@ const emit = defineEmits<{
'search-change'
:
[
params
:
Record
<
string
,
any
>
]
'sort-change'
:
[
sort
:
Record
<
string
,
any
>
]
'page-change'
:
[
pageInfo
:
Pagination
]
clear
:
[]
change
:
[
changeParams
:
any
]
}
>
()
// 清空
const
handleClear
=
()
=>
{
emit
(
'clear'
)
}
// 列配置项
const
columnControllerVisible
=
ref
(
false
)
const
columnControllerConfig
=
computed
<
TableProps
[
'columnController'
]
>
(()
=>
({
...
...
src/components/PageFilters/index.vue
浏览文件 @
a9ae07d6
...
...
@@ -7,6 +7,7 @@
<t-input
v-model=
"item.str"
clearable
v-bind=
"item.$attrs"
:placeholder=
"item.label"
:style=
"
{ width: (item.width || 160) + 'px' }"
v-if="item.type === 'input'"
...
...
@@ -19,6 +20,7 @@
v-model=
"item.str"
:placeholder=
"item.label"
clearable
v-bind=
"item.$attrs"
:style=
"{ width: (item.width || 160) + 'px' }"
v-if=
"item.type === 'select' && item.selectData"
>
...
...
@@ -26,6 +28,7 @@
</t-select>
<t-select
v-model=
"item.values"
v-bind=
"item.$attrs"
:placeholder=
"item.label"
clearable
multiple
...
...
@@ -41,6 +44,7 @@
allow-input
clearable
:placeholder=
"item.label"
v-bind=
"item.$attrs"
:style=
"{ width: (item.width || 160) + 'px' }"
v-if=
"item.type === 'date'"
/>
...
...
@@ -96,17 +100,6 @@ const props = withDefaults(defineProps<PageFiltersProps>(), {
const
filterData
=
ref
<
filterItemProp
[]
>
([])
const
minCollapsedNum
:
SelectProps
[
'minCollapsedNum'
]
=
1
watch
(
()
=>
props
.
filterConditions
,
(
val
:
filterItemProp
[])
=>
{
filterData
.
value
=
val
},
{
deep
:
true
,
immediate
:
true
}
)
// 判断是否显示筛选结果区域
const
isShowFilterResult
=
computed
(()
=>
filterData
.
value
.
find
((
v
:
filterItemProp
)
=>
v
.
str
||
v
.
values
?.
length
))
...
...
@@ -120,7 +113,7 @@ const handleClear = () => {
item
.
str
=
''
item
.
values
=
[]
})
handleFilterSearch
(
)
emit
(
'clear'
)
}
// 展示筛选内容的结果(select、input)
...
...
@@ -151,6 +144,7 @@ const filterParams: DynamicType = reactive({})
const
emit
=
defineEmits
<
{
'on-filter'
:
[
filter
:
DynamicType
[
'filter'
]]
clear
:
[]
}
>
()
const
handleFilterSearch
=
()
=>
{
...
...
@@ -166,6 +160,29 @@ const resetFilterConditions = () => {
})
return
filterParams
}
watch
(
()
=>
props
.
filterConditions
,
(
val
:
filterItemProp
[])
=>
{
filterData
.
value
=
val
},
{
deep
:
true
,
immediate
:
true
}
)
watch
(
()
=>
filterData
,
()
=>
{
handleFilterSearch
()
},
{
deep
:
true
,
immediate
:
true
}
)
defineExpose
<
DynamicType
>
({
resetFilterConditions
})
...
...
src/components/PageFilters/interface/index.ts
浏览文件 @
a9ae07d6
/*
* @Author: xiejiang
* @Date: 2024-12-08 09:25:35
* @LastEditors: xiejiang
* @LastEditTime: 2024-12-09 18:10:59
* @Description:
* Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved.
*/
// 下拉选项数据结构
export
interface
SelectOption
{
label
:
string
// 显示文本
...
...
@@ -22,6 +30,7 @@ export interface filterItemProp {
closable
?:
boolean
placeholder
?:
string
// 占位文本
disabled
?:
boolean
// 是否禁用
$attrs
?:
any
}
// 筛选组件Props
export
interface
PageFiltersProps
{
...
...
src/components/SearchWithButton/index.vue
浏览文件 @
a9ae07d6
...
...
@@ -2,7 +2,7 @@
* @Author: xiejiang
* @Date: 2023-07-13 10:27:58
* @LastEditors: xiejiang
* @LastEditTime: 2024-12-0
6 14:33:05
* @LastEditTime: 2024-12-0
9 17:36:28
* @Description: 搜索组件
-->
<
template
>
...
...
@@ -13,7 +13,7 @@
:placeholder=
"placeholder"
borderless
@
enter=
"handleFullySearch"
@
clear=
"handleClearSearch"
:on-
clear=
"handleClearSearch"
>
<template
#
prefix-icon
>
<SearchIcon
/>
...
...
@@ -24,7 +24,7 @@
</template>
<
script
setup
name=
"SearchWithButton"
lang=
"ts"
>
const
emit
=
defineEmits
([
'update:modelValue'
,
'onSearch'
,
'
onC
lear'
])
const
emit
=
defineEmits
([
'update:modelValue'
,
'onSearch'
,
'
c
lear'
])
const
props
=
defineProps
({
modelValue
:
{
type
:
String
,
...
...
@@ -49,7 +49,8 @@ const props = defineProps({
})
const
searchKey
=
ref
(
''
)
const
handleClearSearch
=
()
=>
{
emit
(
'onClear'
)
emit
(
'update:modelValue'
,
searchKey
.
value
)
emit
(
'clear'
)
}
const
handleFullySearch
=
()
=>
{
emit
(
'onSearch'
,
searchKey
.
value
)
...
...
src/components/WangEditor/index.vue
浏览文件 @
a9ae07d6
...
...
@@ -71,6 +71,14 @@ const props = defineProps({
disabled
:
{
type
:
Boolean
,
default
:
false
},
maxlength
:
{
type
:
Number
,
default
:
9999
},
placeholder
:
{
type
:
String
,
default
:
'请输入内容'
}
})
...
...
src/routers/index.ts
浏览文件 @
a9ae07d6
...
...
@@ -116,7 +116,10 @@ router.beforeEach(async (to, from, next) => {
// 存储当前激活菜单,如果当前不需要tab,则激活activeMenu
authStore
.
setMenuSign
(
to
.
meta
?.
activeMenu
?
(
to
.
meta
.
activeMenu
as
string
)
:
(
to
.
name
as
string
))
const
activeMenuId
=
findMenuByName
(
authStore
.
authMenuListGet
,
to
.
name
as
string
)?.
menuId
??
''
if
(
activeMenuId
)
{
authStore
.
setActiveMenuId
(
activeMenuId
)
}
next
()
return
// }
...
...
src/views/customer/institution/detail.vue
浏览文件 @
a9ae07d6
...
...
@@ -2,7 +2,7 @@
* @Author: xiejiang
* @Date: 2024-12-01 10:37:37
* @LastEditors: xiejiang
* @LastEditTime: 2024-12-0
5 15:14:43
* @LastEditTime: 2024-12-0
9 15:48:06
* @Description: 机构详情
* Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved.
-->
...
...
@@ -11,10 +11,17 @@
<Back
/>
<main
class=
"m-auto max-w-[1012px]"
>
<!-- 基本信息 -->
<PageTitle
title=
"基本信息"
class=
"mb-[24px] mt-[12px]"
/>
<PageTitle
class=
"mb-[24px] mt-[12px]"
>
<div
class=
"flex items-center"
>
<span>
基本信息
</span>
<t-button
shape=
"round"
class=
"ml-[12px]"
theme=
"primary"
size=
"small"
variant=
"outline"
@
click=
"handelEdit"
>
编辑机构
</t-button
>
</div>
</PageTitle>
<div
class=
"flex flex-wrap"
>
<DetailTable
label=
"机构名称"
:value=
"state?.companyName"
/>
<DetailTable
label=
"机构类型"
:value=
"state?.companyType"
/>
<DetailTable
label=
"机构类型"
:value=
"state?.companyType
Name
"
/>
<DetailTable
label=
"机构状态"
><span>
{{
statusTxt
(
state
?.
companyStatus
as
number
)?.
title
}}
...
...
@@ -36,13 +43,15 @@
</
template
>
<
script
setup
lang=
"ts"
name=
"institution-detail"
>
import
{
useRoute
}
from
'vue-router'
import
{
useRoute
,
useRouter
}
from
'vue-router'
import
{
useBasic
}
from
'@/hooks/useBasic'
import
{
statusTxt
}
from
'@/utils/status'
import
{
ResCompany
}
from
'@/api/interface/institution/index'
import
{
getDetail
}
from
'@/api/modules/institution/index'
const
{
setBreadcrumb
}
=
useBasic
()
const
route
=
useRoute
()
const
router
=
useRouter
()
const
state
=
ref
<
ResCompany
>
()
...
...
@@ -52,7 +61,15 @@ const getData = () => {
})
}
const
{
setBreadcrumb
}
=
useBasic
()
// 编辑新增
const
handelEdit
=
()
=>
{
router
.
push
({
name
:
'institution-edit'
,
query
:
{
companyId
:
route
.
query
.
companyId
}
})
}
onMounted
(()
=>
{
setBreadcrumb
([
...
...
src/views/customer/institution/edit.vue
浏览文件 @
a9ae07d6
...
...
@@ -2,7 +2,7 @@
* @Author: xiejiang
* @Date: 2024-12-01 10:26:11
* @LastEditors: xiejiang
* @LastEditTime: 2024-12-0
5 10:59:59
* @LastEditTime: 2024-12-0
9 17:44:36
* @Description: 新增编辑角色
* Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved.
-->
...
...
@@ -26,7 +26,11 @@
<t-form-item
label=
"管理员手机号码"
name=
"adminUserMobile"
>
<t-input
maxlength=
"11"
@
input=
"v => (formData.adminUserMobile = v.replace(/[^0-9]/g, ''))"
@
input=
"
v =>
{
formData.adminUserMobile = v.target.value.replace(/[^0-9]/g, '')
}
"
v-model="formData.adminUserMobile"
placeholder="请输入管理员手机号码"
>
...
...
@@ -40,14 +44,14 @@
v-model=
"formData.serviceTerminationTime"
clearable
type=
"date"
:disable-date=
"
{ before:
'2023-12-31'
}"
:disable-date=
"
{ before:
dayjs().subtract(1, 'day').format('YYYY-MM-DD')
}"
placeholder="请选择时间"
/>
<p
class=
"text-[var(--td-warning-color-6)] text-[12px] m-0 times"
>
机构服务的结束时间为该日期当日23:59:59
</p>
</t-form-item>
<t-form-item
label=
"机构备注"
name=
"remark"
>
<t-textarea
maxlength=
"200"
v-model=
"formData.remark"
placeholder=
"请输入内容"
>
</t-textarea>
<t-textarea
:
maxlength=
"200"
v-model=
"formData.remark"
placeholder=
"请输入内容"
>
</t-textarea>
</t-form-item>
</t-form>
...
...
@@ -64,6 +68,7 @@
<
script
setup
lang=
"ts"
name=
"institution-edit"
>
import
{
useRoute
,
useRouter
}
from
'vue-router'
import
{
FormProps
,
FormInstanceFunctions
,
CustomValidator
}
from
'tdesign-vue-next'
import
dayjs
from
'dayjs'
import
{
useBasic
}
from
'@/hooks/useBasic'
import
{
isPhoneNumber
}
from
'@/utils'
import
{
ReqCompany
}
from
'@/api/interface/institution/index'
...
...
@@ -207,7 +212,7 @@ onMounted(() => {
name
:
'institution'
},
{
title
:
route
.
query
.
companyId
?
'
添加机构'
:
'修改
机构'
title
:
route
.
query
.
companyId
?
'
修改机构'
:
'添加
机构'
}
])
getDictData
()
...
...
src/views/customer/institution/index.vue
浏览文件 @
a9ae07d6
...
...
@@ -2,7 +2,7 @@
* @Author: xiejiang
* @Date: 2024-11-28 15:01:02
* @LastEditors: xiejiang
* @LastEditTime: 2024-12-0
8 14:43:35
* @LastEditTime: 2024-12-0
9 16:35:49
* @Description: 机构管理
* Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved.
-->
...
...
@@ -22,6 +22,7 @@
:loading=
"loading"
placeholder=
"机构名称"
v-model=
"companyName"
@
clear=
"handleClear"
@
on-search=
"handleSearch(searchParams)"
/></
template
>
...
...
@@ -78,7 +79,6 @@ onMounted(() => {
}
])
getDictData
()
getData
()
})
// 加载状态
...
...
@@ -135,7 +135,20 @@ const columns: PrimaryTableCol[] = [
title
:
'机构类型'
,
colKey
:
'companyTypeName'
},
{
title
:
'机构管理员'
,
colKey
:
'adminUserName'
},
{
title
:
'机构管理员'
,
colKey
:
'adminUserName'
,
ellipsis
:
true
,
cell
:
(
h
,
{
row
})
=>
{
return
(
<
div
class
=
'flex items-center'
>
<
span
>
{
row
.
adminUserName
}({
row
.
adminUserMobile
})
<
/span
>
<
/div
>
)
}
},
{
title
:
'服务到期时间'
,
colKey
:
'serviceTerminationTime'
},
{
title
:
'机构状态'
,
...
...
@@ -176,7 +189,7 @@ const getData = () => {
const
postData
=
{
...
pagination
.
value
,
...
searchParams
.
value
,
co
ndRole
Name
:
companyName
.
value
co
mpany
Name
:
companyName
.
value
}
getCompanyList
(
postData
)
.
then
(
res
=>
{
...
...
@@ -196,6 +209,12 @@ const handleSearch = (params: Record<string, any>) => {
getData
()
}
const
handleClear
=
()
=>
{
companyName
.
value
=
''
pagination
.
value
.
page
=
1
getData
()
}
// 处理分页
const
handlePage
=
(
pageInfo
:
Pagination
)
=>
{
pagination
.
value
=
{
...
pagination
.
value
,
...
pageInfo
}
...
...
src/views/login/index.vue
浏览文件 @
a9ae07d6
...
...
@@ -2,7 +2,7 @@
* @Author: xiejiang
* @Date: 2024-11-05 10:14:56
* @LastEditors: xiejiang
* @LastEditTime: 2024-12-0
8 14:31:01
* @LastEditTime: 2024-12-0
9 09:17:08
* @Description: 登录
* Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved.
-->
...
...
@@ -22,6 +22,7 @@
<t-input
v-model=
"formData.mobile"
maxlength=
"11"
clearable
@
input=
"
v =>
{
formData.mobile = v.target.value.replace(/[^0-9]/g, '')
...
...
src/views/sys-config/dictionary/dictionary-subset.vue
浏览文件 @
a9ae07d6
...
...
@@ -2,7 +2,7 @@
* @Author: xiejiang
* @Date: 2024-11-11 09:38:40
* @LastEditors: xiejiang
* @LastEditTime: 2024-12-0
8 15:49:0
3
* @LastEditTime: 2024-12-0
9 15:15:3
3
* @Description: 系统字典-管理子集
* Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved.
-->
...
...
@@ -134,23 +134,18 @@ const columns: PrimaryTableCol[] = [
title
:
'快速排序'
,
colKey
:
'sort'
,
width
:
88
,
cell
:
(
h
,
{
row
,
rowIndex
}:
{
row
:
any
;
rowIndex
:
number
})
=>
{
cell
:
(
h
,
{
row
}:
{
row
:
any
})
=>
{
return
(
<
div
class
=
'flex items-center text-[var(--td-brand-color)]'
>
<
operate
-
btn
content
=
''
class
=
'ico-btn'
disabled
=
{
row
Index
==
0
?
true
:
false
}
disabled
=
{
row
.
isFirst
?
true
:
false
}
onClick
=
{
handleSort
(
row
,
false
)}
>
<
ArrowUpIcon
/>
<
/operate-btn
>
<
operate
-
btn
content
=
''
class
=
'ico-btn'
disabled
=
{
rowIndex
==
tableData
.
value
.
length
-
1
?
true
:
false
}
onClick
=
{
handleSort
(
row
,
true
)}
>
<
operate
-
btn
content
=
''
class
=
'ico-btn'
disabled
=
{
row
.
isLast
?
true
:
false
}
onClick
=
{
handleSort
(
row
,
true
)}
>
<
ArrowDownIcon
/>
<
/operate-btn
>
<
/div
>
...
...
@@ -233,7 +228,7 @@ const GetDictDataList = () => {
loading
.
value
=
true
getGetDictDataList
({
dictId
:
route
.
query
.
dictId
as
string
})
.
then
(
res
=>
{
tableData
.
value
=
res
.
data
tableData
.
value
=
res
.
data
||
[]
pagination
.
value
.
total
=
res
?.
recordsFiltered
as
number
})
.
finally
(()
=>
{
...
...
src/views/sys-config/dictionary/index.vue
浏览文件 @
a9ae07d6
...
...
@@ -2,7 +2,7 @@
* @Author: xiejiang
* @Date: 2024-11-11 09:38:40
* @LastEditors: xiejiang
* @LastEditTime: 2024-12-0
8 11:34:20
* @LastEditTime: 2024-12-0
9 16:36:11
* @Description: 系统字典
* Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved.
-->
...
...
@@ -23,6 +23,7 @@
placeholder=
"搜索字典大类,字典名称"
v-model=
"categoryNameOrDictName"
@
on-search=
"handleSearch(searchParams)"
@
clear=
"handleClear"
/></
template
>
<
template
#
header-right
>
...
...
@@ -36,10 +37,10 @@
<
template
#
operation=
"{ row }"
>
<operate-btn
v-if=
"row.status != '2'"
content=
"启用"
@
click=
"handelStatus(row, 2)"
>
</operate-btn>
<operate-btn
content=
"编辑"
@
click=
"handelEdit(row)"
>
</operate-btn>
<operate-btn
content=
"管理子集"
@
click=
"handelSubset(row)"
>
</operate-btn>
<operate-btn
v-if=
"row.isAllowEdit"
content=
"编辑"
@
click=
"handelEdit(row)"
>
</operate-btn>
<operate-btn
v-if=
"row.isAllowAddsub"
content=
"管理子集"
@
click=
"handelSubset(row)"
>
</operate-btn>
<operate-btn
v-if=
"row.status == '2'"
content=
"停用"
@
click=
"handelStatus(row, 1)"
>
</operate-btn>
<operate-btn
v-if=
"row.
status != '2'
"
content=
"删除"
@
click=
"handelDel(row)"
></operate-btn>
<operate-btn
v-if=
"row.
isAllowDelete
"
content=
"删除"
@
click=
"handelDel(row)"
></operate-btn>
</
template
>
</PageContainer>
...
...
@@ -78,7 +79,6 @@ onMounted(() => {
title
:
'系统字典'
}
])
getData
()
})
const
dictionaryEditRef
=
ref
()
...
...
@@ -121,7 +121,7 @@ const columns: PrimaryTableCol[] = [
colKey
:
'serial-number'
,
width
:
70
},
{
title
:
'字典大类'
,
colKey
:
'category
Id
'
},
{
title
:
'字典大类'
,
colKey
:
'category
Name
'
},
{
title
:
'字典名称'
,
colKey
:
'dictName'
},
{
title
:
'字典编码'
,
colKey
:
'dictCode'
},
{
title
:
'字典说明'
,
colKey
:
'remark'
},
...
...
@@ -154,8 +154,8 @@ const columns: PrimaryTableCol[] = [
)
}
},
{
title
:
'
创建
人'
,
colKey
:
'inputUserName'
},
{
title
:
'
创建
时间'
,
colKey
:
'inputTime'
},
{
title
:
'
添加
人'
,
colKey
:
'inputUserName'
},
{
title
:
'
添加
时间'
,
colKey
:
'inputTime'
},
{
title
:
'操作'
,
colKey
:
'operation'
,
fixed
:
'right'
,
width
:
260
}
]
...
...
@@ -205,6 +205,13 @@ const handleSearch = (params: Record<string, any>) => {
getData
()
}
// 清空搜索条件
const
handleClear
=
()
=>
{
categoryNameOrDictName
.
value
=
''
pagination
.
value
.
page
=
1
getData
()
}
// 处理分页
const
handlePage
=
(
pageInfo
:
Pagination
)
=>
{
pagination
.
value
=
{
...
pagination
.
value
,
...
pageInfo
}
...
...
src/views/sys-config/dictionary/page/dictionary-edit.vue
浏览文件 @
a9ae07d6
...
...
@@ -56,7 +56,7 @@
</t-form-item>
<t-form-item
label=
"字典说明"
name=
"remark"
>
<t-textarea
maxlength=
"200"
v-model=
"formData.remark"
placeholder=
"请输入字典说明"
>
</t-textarea>
<t-textarea
:
maxlength=
"200"
v-model=
"formData.remark"
placeholder=
"请输入字典说明"
>
</t-textarea>
</t-form-item>
</t-form>
</Drawer>
...
...
@@ -170,10 +170,6 @@ defineExpose({
</
script
>
<
style
lang=
"less"
scoped
>
:deep(.t-textarea__limit) {
display: none;
}
:deep(.t-radio__label) {
color: var(--td-font-gray-2);
}
...
...
src/views/sys-config/dictionary/page/dictionary-subset-edit.vue
浏览文件 @
a9ae07d6
...
...
@@ -22,10 +22,10 @@
<t-input
maxlength=
"20"
v-model=
"formData.valueName"
placeholder=
"请输入内容"
>
</t-input>
</t-form-item>
<t-form-item
label=
"值编码"
name=
"dataCode"
>
<t-input
v-model=
"formData.dataCode"
placeholder=
"请输入内容"
>
</t-input>
<t-input
v-model=
"formData.dataCode"
maxlength=
"50"
placeholder=
"请输入内容"
>
</t-input>
</t-form-item>
<t-form-item
label=
"值备注"
name=
"remark"
>
<t-textarea
maxlength=
"200"
v-model=
"formData.remark"
placeholder=
"请输入内容"
>
</t-textarea>
<t-textarea
:
maxlength=
"200"
v-model=
"formData.remark"
placeholder=
"请输入内容"
>
</t-textarea>
</t-form-item>
</t-form>
</Drawer>
...
...
@@ -111,9 +111,3 @@ defineExpose({
close
})
</
script
>
<
style
lang=
"less"
scoped
>
:deep(.t-textarea__limit) {
display: none;
}
</
style
>
src/views/sys-config/menu/index.vue
浏览文件 @
a9ae07d6
...
...
@@ -2,7 +2,7 @@
* @Author: xiejiang
* @Date: 2024-11-11 09:38:40
* @LastEditors: xiejiang
* @LastEditTime: 2024-12-0
8 15:05:16
* @LastEditTime: 2024-12-0
9 16:40:03
* @Description: 菜单管理
* Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved.
-->
...
...
@@ -10,7 +10,7 @@
<div
class=
"h-full overflow-auto"
>
<t-tabs
class=
"px-[16px]"
v-model=
"tabValue"
:on-change=
"onTabChange"
>
<t-tab-panel
:value=
"0"
label=
"平台菜单"
:destroy-on-hide=
"false"
/>
<t-tab-panel
:value=
"1"
label=
"机构菜单"
:destroy-on-hide=
"false"
/>
<t-tab-panel
:value=
"1"
:disabled=
"true"
label=
"机构菜单"
:destroy-on-hide=
"false"
/>
</t-tabs>
<PageContainer
...
...
@@ -31,6 +31,7 @@
:loading=
"loading"
placeholder=
"搜索菜单名称"
v-model=
"condMenuName"
@
clear=
"handleClear"
@
on-search=
"handleSearch(searchParams)"
/></
template
>
<
template
#
header-right
>
...
...
@@ -110,13 +111,17 @@ onMounted(() => {
title
:
'菜单管理'
}
])
getData
()
GetAllMenuGroup
()
})
// 搜索参数类型
const
filterConditions
=
ref
<
filterItemProp
[]
>
([])
// 表格列配置
const
columns
:
PrimaryTableCol
[]
=
[
{
title
:
'序号'
,
colKey
:
'serial-number'
,
width
:
70
},
{
title
:
'菜单层级'
,
colKey
:
'menuLevel'
,
...
...
@@ -167,6 +172,13 @@ const handleSearch = (params: Record<string, any>) => {
getData
()
}
// 清空搜索条件
const
handleClear
=
()
=>
{
condMenuName
.
value
=
''
pagination
.
value
.
page
=
1
getData
()
}
// 分页变更
const
handlePage
=
(
pageInfo
:
{
page
:
number
;
limit
:
number
})
=>
{
pagination
.
value
=
{
...
pagination
.
value
,
...
pageInfo
}
...
...
src/views/sys-config/menu/page/menu-edit.vue
浏览文件 @
a9ae07d6
...
...
@@ -44,7 +44,7 @@
<t-form-item
v-if=
"formData.menuLevel === 3"
label=
"是否为按钮"
name=
"isButton"
>
<t-radio-group
v-model=
"formData.isButton"
>
<t-radio
:value=
"1"
>
是
</t-radio>
<t-radio
:value=
"
2
"
>
否
</t-radio>
<t-radio
:value=
"
0
"
>
否
</t-radio>
</t-radio-group>
</t-form-item>
<t-form-item
label=
"父级菜单"
name=
"parentId"
v-if=
"formData.menuLevel !== 1"
>
...
...
@@ -211,10 +211,6 @@ defineExpose({
</
script
>
<
style
lang=
"less"
scoped
>
:deep(.t-textarea__limit) {
display: none;
}
:deep(.t-radio__label) {
color: var(--td-font-gray-2);
}
...
...
src/views/sys-config/menu/page/menu-log.vue
浏览文件 @
a9ae07d6
...
...
@@ -19,11 +19,6 @@
<template
v-for=
"(_, name) in $slots"
#[
name
]="
scope
"
>
<slot
:name=
"name"
v-bind=
"scope"
/>
</
template
>
<
template
v-for=
"col in columns"
#[
col
.
colKey
]="{
row
}"
:key=
"col.colKey"
>
<template
v-if=
"col.colKey != 'operation'"
>
<div
class=
"cell-content"
>
{{
row
[
col
.
colKey
]
||
'-'
}}
</div>
</
template
>
</template>
</t-table>
</Drawer>
</template>
...
...
@@ -59,7 +54,7 @@ const columns: PrimaryTableCol[] = [
<
div
class
=
'text-[var(--td-brand-color)]'
>
<
p
>
操作:
{
operateTypeTxt
(
row
.
operateType
)}
<
/p
>
<
p
>
菜单名称:
{
row
.
menuName
}
<
/p
>
<
p
>
路由名称:
{
row
.
menuSign
}
<
/p
>
<
p
>
路由名称:
{
row
.
router
}
<
/p
>
<
p
>
菜单层级:
{
menuLevelTxt
(
row
.
menuLevel
)}
<
/p
>
<
/div
>
)
...
...
src/views/sys-config/menu/page/menu-sort.vue
浏览文件 @
a9ae07d6
...
...
@@ -2,12 +2,12 @@
* @Author: xiejiang
* @Date: 2024-12-04 14:06:18
* @LastEditors: xiejiang
* @LastEditTime: 2024-12-0
8 10:39:51
* @LastEditTime: 2024-12-0
9 16:51:19
* @Description: 菜单排序
* Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved.
-->
<
template
>
<Drawer
:drawer-visible=
"drawerVisible"
width=
"480"
title=
"菜单排序"
:
show-
footer=
"false"
@
close=
"close"
>
<Drawer
:drawer-visible=
"drawerVisible"
width=
"480"
title=
"菜单排序"
:footer=
"false"
@
close=
"close"
>
<t-tree
:data=
"menuTree"
activable
...
...
src/views/sys-config/version/index.vue
浏览文件 @
a9ae07d6
...
...
@@ -2,7 +2,7 @@
* @Author: xiejiang
* @Date: 2024-11-11 09:38:40
* @LastEditors: xiejiang
* @LastEditTime: 2024-12-0
5 15:19:07
* @LastEditTime: 2024-12-0
9 18:22:42
* @Description: 版本管理
* Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved.
-->
...
...
@@ -65,6 +65,7 @@
</template>
<
script
setup
lang=
"tsx"
name=
"version"
>
import
dayjs
from
'dayjs'
import
{
PrimaryTableCol
,
MessagePlugin
}
from
'tdesign-vue-next'
import
type
{
filterItemProp
}
from
'src/components/PageFilters/interface/index'
import
type
{
Pagination
}
from
'src/components/PageContainer/interface/index'
...
...
@@ -95,14 +96,19 @@ onMounted(() => {
title
:
'版本管理'
}
])
getData
()
//
getData()
})
// 搜索参数类型
const
filterConditions
=
ref
<
filterItemProp
[]
>
([
{
label
:
'上线时间'
,
prop
:
'onlineTime'
,
type
:
'date'
type
:
'date'
,
$attrs
:
{
'disable-date'
:
(
date
:
string
)
=>
{
return
dayjs
(
date
).
isBefore
(
dayjs
().
format
(
'YYYY-MM'
))
||
dayjs
(
date
).
isAfter
(
dayjs
().
format
(
'YYYY-MM-DD'
))
}
}
},
{
label
:
'版本状态'
,
...
...
@@ -117,6 +123,11 @@ const filterConditions = ref<filterItemProp[]>([
])
// 表格列配置
const
columns
:
PrimaryTableCol
[]
=
[
{
title
:
'序号'
,
colKey
:
'serial-number'
,
width
:
70
},
{
title
:
'版本号'
,
colKey
:
'version'
},
{
title
:
'版本状态'
,
...
...
@@ -233,7 +244,7 @@ const getData = () => {
.
then
(
res
=>
{
tableData
.
value
=
res
.
data
.
pageInfo
.
list
publishedNum
.
value
=
res
.
data
?.
publishedNum
pagination
.
value
.
total
=
res
.
data
?.
total
pagination
.
value
.
total
=
res
.
data
?.
pageInfo
?.
total
})
.
catch
(()
=>
{
tableData
.
value
=
[]
...
...
src/views/sys-config/version/page/version-detail.vue
浏览文件 @
a9ae07d6
<!--
* @Author: xiejiang
* @Date: 2024-12-08 09:25:35
* @LastEditors: xiejiang
* @LastEditTime: 2024-12-09 18:01:54
* @Description:
* Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved.
-->
<
template
>
<Drawer
:drawer-visible=
"drawerVisible"
width=
"480px"
title=
"版本详情"
@
close=
"close"
:
show-
footer=
"false"
>
<Drawer
:drawer-visible=
"drawerVisible"
width=
"480px"
title=
"版本详情"
@
close=
"close"
:footer=
"false"
>
<InfoLable
class=
"mb-[16px]"
label=
"当前终端"
:value=
"props.tabType == 1 ? '平台端' : '机构端'"
/>
<InfoLable
class=
"mb-[16px]"
label=
"版本号"
:value=
"state.version"
/>
<InfoLable
class=
"mb-[16px]"
label=
"更新说明"
><div
v-html=
"state.description || '-'"
></div>
</InfoLable>
...
...
src/views/sys-config/version/page/version-edit.vue
浏览文件 @
a9ae07d6
...
...
@@ -17,6 +17,10 @@
<t-form-item
label=
"更新说明"
name=
"description"
>
<WangEditor
height=
"300px"
:editor-config=
"
{
placeholder: '请输入版本更新说明',
maxLength: 200
}"
:toolbar-config="{
excludeKeys: ['uploadImage', 'uploadVideo'] // 添加这两项以排除图片和视频上传选项
}"
...
...
@@ -24,7 +28,7 @@
/>
</t-form-item>
<t-form-item
label=
"版本备注"
name=
"remark"
>
<t-textarea
maxlength=
"200"
v-model=
"formData.remark"
placeholder=
"请输入版本备注"
>
</t-textarea>
<t-textarea
:
maxlength=
"200"
v-model=
"formData.remark"
placeholder=
"请输入版本备注"
>
</t-textarea>
</t-form-item>
</t-form>
</Drawer>
...
...
@@ -134,10 +138,6 @@ defineExpose({
</
script
>
<
style
lang=
"less"
scoped
>
:deep(.t-textarea__limit) {
display: none;
}
.form {
border-top: 1px solid var(--td-font-gray-4);
}
...
...
src/views/sys-permissions/authority/index.vue
浏览文件 @
a9ae07d6
...
...
@@ -2,7 +2,7 @@
* @Author: xiejiang
* @Date: 2024-11-11 09:38:40
* @LastEditors: xiejiang
* @LastEditTime: 2024-12-0
8 10:28:35
* @LastEditTime: 2024-12-0
9 17:44:49
* @Description: 权限配置
* Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved.
-->
...
...
@@ -15,10 +15,13 @@
<li
v-for=
"v in roles"
:key=
"v.roleId"
:class=
"v.roleId === roleId ? 'li-active' : ''"
:class=
"
v.roleId === roleId ? 'li-active flex justify-between items-center' : ' flex justify-between items-center'
"
@
click=
"roleId = v.roleId"
>
{{
v
.
roleName
}}
<span>
{{
v
.
roleName
}}
</span>
<span>
{{
v
.
userNumber
}}
人
</span>
</li>
</ul>
</div>
...
...
@@ -63,12 +66,9 @@
sourceMenuId = val
}
"
v-
show
="tabValue === 2"
v-
if
="tabValue === 2"
/>
</div>
<CopyPermissions
ref=
"copyPermissionsRef"
/>
<!-- 添加角色 -->
<!--
<Dialog
:dialog-visible=
"dialogVisible"
width=
"480px"
title=
"添加角色"
:footer=
"true"
@
close=
"close"
>
<template
#
body
>
...
...
@@ -107,7 +107,6 @@ import { ResRoleList } from '@/api/interface/user-roles/index'
import
{
getRoleList
}
from
'@/api/modules/user-roles/index'
import
Capabilities
from
'./page/capabilities.vue'
import
DataPermissions
from
'./page/data-permissions.vue'
import
CopyPermissions
from
'./page/copy-permissions.vue'
import
{
useBasic
}
from
'@/hooks/useBasic'
const
{
setBreadcrumb
}
=
useBasic
()
...
...
@@ -188,7 +187,7 @@ const submitLoading = ref(false)
const
capabilitiesRef
=
ref
()
const
dataPermissionsRef
=
ref
()
const
copyPermissionsRef
=
ref
()
//
const copyPermissionsRef = ref()
const
handleSearchTree
=
()
=>
{
if
(
tabValue
.
value
==
1
)
{
capabilitiesRef
.
value
?.
getData
()
...
...
@@ -208,10 +207,11 @@ const handleClear = () => {
if
(
tabValue
.
value
==
1
)
{
capabilitiesRef
.
value
?.
clear
()
}
else
{
// 应用其他菜单
if
(
!
sourceMenuId
.
value
)
{
return
MessagePlugin
.
error
(
'请选择菜单'
)
}
copyPermissionsRef
.
value
?.
open
(
roleId
.
value
,
sourceMenuId
.
value
)
dataPermissionsRef
.
value
?.
copyPermissions
(
roleId
.
value
,
sourceMenuId
.
value
)
}
}
...
...
src/views/sys-permissions/authority/page/capabilities.vue
浏览文件 @
a9ae07d6
...
...
@@ -2,7 +2,7 @@
* @Author: xiejiang
* @Date: 2024-12-05 17:16:22
* @LastEditors: xiejiang
* @LastEditTime: 2024-12-0
6 15:17:15
* @LastEditTime: 2024-12-0
9 10:15:38
* @Description: 功能权限
* Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved.
-->
...
...
@@ -55,17 +55,13 @@ const props = defineProps({
})
watch
([
toRef
(
props
,
'roleId'
)],
()
=>
{
try
{
getData
()
}
catch
{
MessagePlugin
.
error
(
'获取菜单树失败'
)
}
})
const
loading
=
ref
(
false
)
const
menuTree
=
ref
<
ResMenuTree
[]
>
([])
// 勾选
function
findNodeById
(
tree
:
ResMenuTree
[],
id
:
number
)
{
function
findNodeById
(
tree
:
ResMenuTree
[],
id
:
string
)
{
tree
.
forEach
(
it
=>
{
if
(
it
.
menuId
==
id
)
{
it
.
selected
=
true
...
...
@@ -84,16 +80,16 @@ const handleSelectAll = (itx: ResMenuTree) => {
// 勾选则需要勾选父级
if
(
itx
.
selected
)
{
if
(
itx
.
parentId
)
{
findNodeById
(
menuTree
.
value
,
itx
.
parentId
as
number
)
findNodeById
(
menuTree
.
value
,
itx
.
parentId
as
string
)
}
}
else
{
// 取消后面所有子集
if
(
itx
.
children
)
{
itx
.
children
.
forEach
((
v
:
ResMenuTree
)
=>
{
v
.
selected
=
itx
.
selected
v
.
selected
=
false
if
(
v
.
children
)
{
v
.
children
.
forEach
((
val
:
ResMenuTree
)
=>
{
val
.
selected
=
itx
.
selected
val
.
selected
=
false
})
}
})
...
...
src/views/sys-permissions/authority/page/copy-permissions.vue
浏览文件 @
a9ae07d6
...
...
@@ -2,7 +2,7 @@
* @Author: xiejiang
* @Date: 2024-12-06 17:31:56
* @LastEditors: xiejiang
* @LastEditTime: 2024-12-0
8 10:25:04
* @LastEditTime: 2024-12-0
9 17:31:06
* @Description:
* Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved.
-->
...
...
@@ -10,7 +10,7 @@
<Drawer
:drawer-visible=
"drawerVisible"
width=
"480px"
title=
"
权限克隆
"
title=
"
应用至其他菜单
"
:loading=
"submitLoading"
confirm-btn-text=
"保存"
:cancel-btn=
"false"
...
...
@@ -18,11 +18,11 @@
@
close=
"close"
>
<t-tree
:data=
"menuTree"
:data=
"
props.
menuTree"
:checkable=
"true"
v-model=
"allChecked"
expand-all
value-mode=
"
all
"
value-mode=
"
parentFirst
"
activable
hover
transition
...
...
@@ -34,48 +34,57 @@
<
script
setup
lang=
"ts"
>
import
{
MessagePlugin
}
from
'tdesign-vue-next'
import
{
ResMenuTree
}
from
'@/api/interface/menu/index'
import
{
getMenuTree
,
postDataRangeClone
}
from
'@/api/modules/menu/index'
import
{
postDataRangeClone
}
from
'@/api/modules/menu/index'
const
menuTree
=
ref
<
ResMenuTree
[]
>
([])
const
props
=
withDefaults
(
defineProps
<
{
menuTree
:
ResMenuTree
[]
}
>
(),
{
menuTree
:
()
=>
[]
as
ResMenuTree
[]
}
)
// const menuTree = ref
<
ResMenuTree
[]
>
([])
const
drawerVisible
=
ref
(
false
)
const
submitLoading
=
ref
(
false
)
const
loading
=
ref
(
false
)
//
const loading = ref(false)
const
roleId
=
ref
(
''
)
const
sourceMenuId
=
ref
(
''
)
const
allChecked
=
ref
([])
// 为树形结构的每个节点添加新参数
function
newParamToTree
(
tree
:
ResMenuTree
[]):
ResMenuTree
[]
{
return
tree
.
map
(
node
=>
{
const
newNode
=
{
...
node
,
children
:
node
?.
children
||
[],
label
:
node
?.
menuName
||
'-'
,
value
:
node
?.
menuId
}
if
(
newNode
.
children
&&
newNode
.
children
.
length
>
0
)
{
newNode
.
children
=
newParamToTree
(
newNode
.
children
)
}
return
newNode
})
}
//
//
为树形结构的每个节点添加新参数
//
function newParamToTree(tree: ResMenuTree[]): ResMenuTree[] {
//
return tree.map(node => {
//
const newNode = {
//
...node,
//
children: node?.children || [],
//
label: node?.menuName || '-',
//
value: node?.menuId
//
}
//
if (newNode.children && newNode.children.length > 0) {
//
newNode.children = newParamToTree(newNode.children)
//
}
//
return newNode
//
})
//
}
const
getData
=
()
=>
{
loading
.
value
=
true
getMenuTree
({})
.
then
(
res
=>
{
menuTree
.
value
=
newParamToTree
(
res
.
data
)
})
.
finally
(()
=>
{
loading
.
value
=
false
})
}
//
const getData = () => {
//
loading.value = true
//
getMenuTree({})
//
.then(res => {
//
menuTree.value = newParamToTree(res.data)
//
})
//
.finally(() => {
//
loading.value = false
//
})
//
}
// 保存权限
const
handleConfirm
=
()
=>
{
if
(
allChecked
.
value
.
length
==
0
)
{
MessagePlugin
.
error
(
'请选择需要
克隆的权限
!'
)
MessagePlugin
.
error
(
'请选择需要
应用到其他的菜单
!'
)
return
}
submitLoading
.
value
=
true
...
...
@@ -97,12 +106,13 @@ const open = (roleID: string, sourceMenuID: string) => {
// 关闭抽屉
const
close
=
()
=>
{
allChecked
.
value
=
[]
drawerVisible
.
value
=
false
}
onMounted
(()
=>
{
getData
()
})
//
onMounted(() => {
//
getData()
//
})
defineExpose
({
open
...
...
src/views/sys-permissions/authority/page/data-permissions.vue
浏览文件 @
a9ae07d6
...
...
@@ -9,6 +9,7 @@
placeholder=
"搜索菜单功能名称"
v-model=
"condMenuName"
@
on-search=
"getData"
@
clear=
"getData"
/>
<t-tree
:data=
"menuTree"
:actived=
"[menuId]"
@
active=
"onTreeAcitve"
activable
hover
transition
>
</t-tree>
...
...
@@ -28,7 +29,21 @@
<t-radio-button
value=
"2"
>
地区
</t-radio-button>
</t-radio-group>
<div
class=
"permissions-main"
>
<t-input
<SearchWithButton
v-if=
"type == '1'"
class=
"max-w-[384px] mb-[20px]"
placeholder=
"搜索角色名称"
v-model=
"roleName"
@
on-search=
"GetRoleList"
@
clear=
"
() =>
{
roleName = ''
GetRoleList()
}
"
/>
<!--
<t-input
v-if=
"type == '1'"
class=
"max-w-[384px] mb-[20px]"
v-model=
"roleName"
...
...
@@ -39,10 +54,10 @@
<template
#
suffixIcon
>
<search-icon
:style=
"
{ cursor: 'pointer' }" />
</
template
>
</t-input>
</t-input>
-->
<!-- 地区 -->
<t-checkbox-group
v-model=
"areas"
v-show=
"type == '2'"
>
<t-checkbox-group
:disabled=
"!menuId"
v-model=
"areas"
v-show=
"type == '2'"
>
<t-checkbox
v-for=
"item in areaList"
:value=
"item.dictDataId"
...
...
@@ -51,13 +66,15 @@
/>
</t-checkbox-group>
<!-- 角色 -->
<t-checkbox-group
v-model=
"roles"
v-show=
"type == '1'"
>
<t-checkbox-group
v-model=
"roles"
:disabled=
"!menuId"
v-show=
"type == '1'"
>
<t-checkbox
v-for=
"item in roleList"
:value=
"item.roleId"
:key=
"item.roleId"
:label=
"item.roleName"
/>
</t-checkbox-group>
</div>
</div>
</div>
</div>
<CopyPermissions
ref=
"copyPermissionsRef"
:menu-tree=
"menuTree"
/>
</div>
</template>
...
...
@@ -69,6 +86,9 @@ import { ResDictionary } from '@/api/interface/dectionory/index'
import
{
getGetDictDataByName
}
from
'@/api/modules/dectionory/index'
import
{
ResRoleList
}
from
'@/api/interface/user-roles/index'
import
{
getRoleList
}
from
'@/api/modules/user-roles/index'
import
CopyPermissions
from
'./copy-permissions.vue'
const
copyPermissionsRef
=
ref
()
const
condMenuName
=
ref
(
''
)
const
loading
=
ref
(
false
)
...
...
@@ -86,26 +106,16 @@ const props = defineProps({
})
watch
([
toRef
(
props
,
'roleId'
)],
()
=>
{
try
{
getData
()
}
catch
{
MessagePlugin
.
error
(
'获取菜单树失败'
)
}
})
watch
(
toRef
(
props
,
'tabValue'
),
(
val
:
number
)
=>
{
try
{
if
(
val
==
2
)
{
getData
()
}
}
catch
{
MessagePlugin
.
error
(
'获取菜单树失败'
)
}
})
watch
(
menuId
,
()
=>
{
console
.
log
(
995
)
emit
(
'updateMenuId'
,
menuId
.
value
)
})
...
...
@@ -136,8 +146,13 @@ const getData = () => {
if
(
Array
.
isArray
(
res
.
data
))
{
// 检查 res.data 是否为数组
menuTree
.
value
=
newParamToTree
(
res
.
data
)
menuId
.
value
=
(
menuTree
.
value
[
0
]?.
menuId
||
''
)
as
string
menuId
.
value
=
menuTree
.
value
[
0
]?.
menuId
||
''
if
(
menuId
.
value
)
{
GetDataRange
()
}
else
{
areas
.
value
=
[]
roles
.
value
=
[]
}
}
else
{
menuId
.
value
=
''
// 如果不是数组,设置为空字符串
menuTree
.
value
=
[]
// 如果不是数组,设置为空数组
...
...
@@ -172,7 +187,7 @@ const roleName = ref('')
const
roleList
=
ref
<
ResRoleList
[]
>
([])
const
GetRoleList
=
()
=>
{
getRoleList
({
status
:
1
,
roleName
:
roleName
.
value
}).
then
(
res
=>
{
getRoleList
({
status
:
2
,
roleName
:
roleName
.
value
}).
then
(
res
=>
{
roleList
.
value
=
res
.
data
})
}
...
...
@@ -182,13 +197,11 @@ const GetDataRange = () => {
loading
.
value
=
true
getDataRange
({
roleId
:
props
.
roleId
,
menuId
:
menuId
.
value
})
.
then
(
res
=>
{
if
(
res
.
data
)
{
if
(
res
.
data
)
{
const
data
=
res
.
data
as
ResDataRange
areas
.
value
=
data
.
areas
?.
map
((
item
:
{
id
:
string
})
=>
item
.
id
)
||
[]
roles
.
value
=
data
.
roles
?.
map
((
item
:
{
id
:
string
})
=>
item
.
id
)
||
[]
}
}
})
.
finally
(()
=>
{
loading
.
value
=
false
...
...
@@ -196,6 +209,10 @@ const GetDataRange = () => {
}
const
submit
=
()
=>
{
if
(
!
menuId
.
value
)
{
return
MessagePlugin
.
error
(
'请选择菜单'
)
}
emit
(
'loading'
,
true
)
// 组装地区数据
const
areaLists
:
AreasRole
[]
=
...
...
@@ -223,15 +240,22 @@ const submit = () => {
})
}
// 调用权限克隆
const
copyPermissions
=
(
roleID
:
string
,
sourceMenuID
:
string
)
=>
{
copyPermissionsRef
.
value
.
open
(
roleID
,
sourceMenuID
)
}
onMounted
(()
=>
{
getAreaList
()
GetRoleList
()
getData
()
})
const
emit
=
defineEmits
([
'loading'
,
'updateMenuId'
])
defineExpose
({
getData
,
submit
submit
,
copyPermissions
})
</
script
>
...
...
src/views/sys-permissions/role/index.vue
浏览文件 @
a9ae07d6
...
...
@@ -2,7 +2,7 @@
* @Author: xiejiang
* @Date: 2024-11-28 15:01:02
* @LastEditors: xiejiang
* @LastEditTime: 2024-12-0
8 14:05:30
* @LastEditTime: 2024-12-0
9 16:33:42
* @Description: 角色管理
* Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved.
-->
...
...
@@ -22,10 +22,11 @@
:loading=
"loading"
placeholder=
"搜索角色名称"
v-model=
"roleName"
@
clear=
"handleClear"
@
on-search=
"handleSearch(searchParams)"
/></
template
>
<
template
#
header-right
>
<div
class=
"flex items-center justify-end gap-2"
>
<div
class=
"flex items-center justify-end gap-2"
v-if=
"buttonPms('role-add-btn')"
>
<t-button
shape=
"round"
theme=
"primary"
@
click=
"handelEdit(null)"
>
<template
#
icon
><AddIcon
/></
template
>
添加角色
</t-button
...
...
@@ -37,7 +38,7 @@
<operate-btn
v-if=
"row.status != 2"
content=
"启用"
@
click=
"handelStatus(row, 2)"
>
</operate-btn>
<operate-btn
v-if=
"row.status != 1"
content=
"详情"
@
click=
"handelDetail(row)"
>
</operate-btn>
<operate-btn
v-if=
"row.status == 2"
content=
"权限配置"
@
click=
"handelPermissions(row)"
>
</operate-btn>
<operate-btn
content=
"编辑"
@
click=
"handelEdit(row)"
>
</operate-btn>
<operate-btn
content=
"编辑"
v-if=
"buttonPms('role-edit-btn')"
@
click=
"handelEdit(row)"
>
</operate-btn>
<operate-btn
v-if=
"row.status == 2"
content=
"停用"
@
click=
"handelStatus(row, 1)"
>
</operate-btn>
<operate-btn
v-if=
"row.status != 2"
content=
"删除"
@
click=
"handelDel(row)"
></operate-btn>
</
template
>
...
...
@@ -53,6 +54,7 @@ import { PrimaryTableCol, MessagePlugin } from 'tdesign-vue-next'
import
type
{
filterItemProp
}
from
'@/components/PageFilters/interface/index'
import
type
{
Pagination
}
from
'@/components/PageContainer/interface/index'
import
{
statusTxt
}
from
'@/utils/status'
import
{
buttonPms
}
from
'@/utils'
import
{
useBasic
}
from
'@/hooks/useBasic'
import
MessageBox
from
'@/utils/messageBox'
import
RoleEdit
from
'./page/role-edit.vue'
...
...
@@ -73,7 +75,7 @@ onMounted(() => {
name
:
'role'
}
])
getData
()
//
getData()
})
// 加载状态
...
...
@@ -139,6 +141,13 @@ const handleSearch = (params: Record<string, any>) => {
getData
()
}
// 清空搜索条件
const
handleClear
=
()
=>
{
roleName
.
value
=
''
pagination
.
value
.
page
=
1
getData
()
}
// 处理分页
const
handlePage
=
(
pageInfo
:
Pagination
)
=>
{
pagination
.
value
=
{
...
pagination
.
value
,
...
pageInfo
}
...
...
@@ -167,7 +176,7 @@ const handelDetail = (row: ResRoleList) => {
router
.
push
({
name
:
'role-detail'
,
query
:
{
i
d
:
row
.
roleId
roleI
d
:
row
.
roleId
}
})
}
...
...
src/views/sys-permissions/role/page/role-edit.vue
浏览文件 @
a9ae07d6
...
...
@@ -22,7 +22,7 @@
<t-input
maxlength=
"20"
v-model=
"formData.roleName"
placeholder=
"请输入角色姓名"
>
</t-input>
</t-form-item>
<t-form-item
label=
"角色描述"
name=
"description"
>
<t-textarea
maxlength=
"200"
v-model=
"formData.description"
placeholder=
"请输入角色备注"
>
</t-textarea>
<t-textarea
:
maxlength=
"200"
v-model=
"formData.description"
placeholder=
"请输入角色备注"
>
</t-textarea>
</t-form-item>
</t-form>
</Drawer>
...
...
@@ -96,9 +96,3 @@ defineExpose({
close
})
</
script
>
<
style
lang=
"less"
scoped
>
:deep(.t-textarea__limit) {
display: none;
}
</
style
>
src/views/sys-permissions/user/detail.vue
浏览文件 @
a9ae07d6
<
template
>
<div
class=
"bg-white p-[12px] h-full overflow-auto"
>
<Back
/>
<main
class=
"m-auto max-w-[1012px]"
>
<main
class=
"m-auto max-w-[1012px]"
v-loading=
"loading"
>
<!-- 基本信息 -->
<PageTitle
title=
"基本信息"
class=
"mb-[24px] mt-[12px]"
/>
<div
class=
"flex flex-wrap"
>
...
...
@@ -9,7 +9,7 @@
<DetailTable
:label=
"'手机号码'"
:value=
"detailData?.mobile"
/>
<DetailTable
label=
"状态"
>
<span>
{{
statusTxt
(
detailData
?.
status
as
number
)?.
title
}}
{{
statusTxt
(
detailData
?.
status
as
number
)?.
title
||
'-'
}}
</span>
</DetailTable>
<DetailTable
:label=
"'添加时间'"
:value=
"detailData?.inputTime"
/>
...
...
@@ -24,17 +24,19 @@
:columns=
"columns"
:loading=
"loading"
@
page-change=
"onPageChange"
row-key=
"ids"
:rowspan-and-colspan=
"rowspanAndColspan"
max-height=
"400px"
:pagination=
"pagination.total > 10 ? pagination : undefined"
>
<!-- 保留自定义列插槽 -->
<template
v-for=
"(_, name) in $slots"
#[
name
]="
scope
"
>
<slot
:name=
"name"
v-bind=
"scope"
/>
</
template
>
<template
v-for=
"col in columns"
#[
col
.
colKey
]="
{ row }" :key="col.colKey">
<template
v-if=
"col.colKey != 'operation'"
>
<div
class=
"cell-content"
>
{{
row
[
col
.
colKey
]
||
'-'
}}
</div>
<template
v-if=
"col.colKey == 'dataPermission'"
>
<div
class=
"cell-content"
>
{{
dataPermissions
(
row
)
||
'-'
}}
</div>
</
template
>
<
template
v-else-if=
"col.colKey == 'functionPermission'"
>
<div
class=
"cell-content"
>
{{
functionPermission
(
row
)
||
'-'
}}
</div>
</
template
>
<
template
v-else
>
{{
row
[
col
.
colKey
]
||
'-'
}}
</
template
>
</template>
</t-table>
...
...
@@ -48,15 +50,6 @@
@
page-change=
"onLogsPageChange"
:pagination=
"paginationLog.total > 10 ? paginationLog : undefined"
>
<!-- 保留自定义列插槽 -->
<
template
v-for=
"(_, name) in $slots"
#[
name
]="
scope
"
>
<slot
:name=
"name"
v-bind=
"scope"
/>
</
template
>
<
template
v-for=
"col in columns"
#[
col
.
colKey
]="{
row
}"
:key=
"col.colKey"
>
<template
v-if=
"col.colKey != 'operation'"
>
<div
class=
"cell-content"
>
{{
row
[
col
.
colKey
]
||
'-'
}}
</div>
</
template
>
</template>
</t-table>
</main>
</div>
...
...
@@ -64,7 +57,7 @@
<
script
setup
lang=
"tsx"
name=
"users-detail"
>
import
{
useRoute
}
from
'vue-router'
import
{
PrimaryTableCol
,
PaginationProps
}
from
'tdesign-vue-next'
import
{
PrimaryTableCol
,
PaginationProps
,
TableProps
}
from
'tdesign-vue-next'
import
{
useBasic
}
from
'@/hooks/useBasic'
import
{
statusTxt
}
from
'@/utils/status'
import
{
getUserDetail
,
getLogs
}
from
'@/api/modules/user-roles/index'
...
...
@@ -79,45 +72,91 @@ const detailData = ref<ResUserList>()
// 获取用户详情
const
getData
=
()
=>
{
loading
.
value
=
true
getUserDetail
({
userId
:
route
.
query
.
userId
as
string
,
...
pagination
.
value
}).
then
(
res
=>
{
})
.
then
(
res
=>
{
detailData
.
value
=
res
.
data
pagination
.
value
.
total
=
res
.
data
?.
roleNames
?.
total
as
number
const
list
=
res
.
data
?.
roleNames
?.
list
||
[]
tableData
.
value
=
list
.
map
(
(
e
:
{
const
tableDatas
=
list
.
map
(
(
e
:
{
menuPermission
:
{
menuName
:
string
buttonNames
:
string
[]
areaPermissions
:
{
areaN
ame
:
string
}[]
rolePermissions
:
{
roleN
ame
:
string
}[]
areaPermissions
:
{
n
ame
:
string
}[]
rolePermissions
:
{
n
ame
:
string
}[]
}[]
})
=>
{
},
index
:
number
)
=>
{
const
lists
=
e
.
menuPermission
.
map
((
em
,
i
:
number
)
=>
{
return
{
...
e
,
...
em
,
ids
:
`
${
index
}
-
${
i
}
`
,
rowspan
:
!
i
?
e
.
menuPermission
.
length
:
0
,
serial
:
index
+
1
}
})
return
[...
lists
]
// 匹配对应格式
let
functionPermission
:
string
[]
=
[]
let
dataPermission
:
string
[]
=
[]
e
.
menuPermission
.
map
(
(
em
:
{
menuName
:
string
buttonNames
:
string
[]
areaPermissions
:
{
areaName
:
string
}[]
rolePermissions
:
{
roleName
:
string
}[]
})
=>
{
functionPermission
.
push
(
em
.
menuName
+
em
.
buttonNames
.
join
(
','
))
dataPermission
.
push
(
em
.
areaPermissions
.
map
((
val
:
{
areaName
:
string
})
=>
val
.
areaName
).
join
(
','
)
+
'-'
+
em
.
rolePermissions
.
map
((
val
:
{
roleName
:
string
})
=>
val
.
roleName
).
join
(
','
)
)
// let functionPermission: string[] = []
// let dataPermission: string[] = []
// e.menuPermission.map(
// (em: {
// menuName: string
// buttonNames: string[]
// areaPermissions: { name: string }[]
// rolePermissions: { name: string }[]
// }) => {
// const buttonNames = em.buttonNames || []
// const areaPermissions = em.areaPermissions || []
// const rolePermissions = em.rolePermissions || []
// functionPermission.push(em.menuName + buttonNames.join(','))
// dataPermission.push(
// areaPermissions.map((val: { name: string }) => val.name).join(',') +
// '-' +
// rolePermissions.map((val: { name: string }) => val.name).join(',')
// )
// }
// )
// return { ...e, functionPermission: functionPermission.join(';'), dataPermission: dataPermission.join(';') }
}
)
tableData
.
value
=
tableDatas
.
flat
()
})
.
finally
(()
=>
{
loading
.
value
=
false
})
}
const
dataPermissions
=
(
row
:
ResUserList
)
=>
{
const
areaPermissions
=
row
.
areaPermissions
||
[]
const
rolePermissions
=
row
.
rolePermissions
||
[]
const
txt
=
areaPermissions
.
map
((
val
:
{
name
:
string
})
=>
val
.
name
).
join
(
','
)
+
'-'
+
rolePermissions
.
map
((
val
:
{
name
:
string
})
=>
val
.
name
).
join
(
','
)
return
txt
}
return
{
...
e
,
functionPermission
:
functionPermission
.
join
(
';'
),
dataPermission
:
dataPermission
.
join
(
';'
)
}
const
functionPermission
=
(
row
:
ResUserList
)
=>
{
const
buttonNames
=
row
.
buttonNames
||
[]
return
row
.
menuName
+
(
buttonNames
.
length
?
'-'
+
buttonNames
.
join
(
','
)
:
''
)
}
// 合并单元格
const
rowspanAndColspan
:
TableProps
[
'rowspanAndColspan'
]
=
({
row
,
colIndex
})
=>
{
if
(
colIndex
===
1
||
colIndex
===
0
)
{
return
{
colspan
:
1
,
rowspan
:
row
?.
rowspan
}
}
else
{
return
{
colspan
:
1
,
rowspan
:
1
}
}
)
})
}
const
onPageChange
=
(
val
:
PaginationProps
)
=>
{
...
...
@@ -154,10 +193,10 @@ const pagination = ref({
const
columns
:
PrimaryTableCol
[]
=
[
{
title
:
'序号'
,
colKey
:
'serial
-number
'
,
colKey
:
'serial'
,
width
:
70
},
{
title
:
'角色名称'
,
colKey
:
'
user
Name'
},
{
title
:
'角色名称'
,
colKey
:
'
role
Name'
},
{
title
:
'功能权限'
,
colKey
:
'functionPermission'
},
{
title
:
'数据权限'
,
colKey
:
'dataPermission'
}
]
...
...
@@ -187,7 +226,7 @@ onMounted(() => {
title
:
'系统权限'
},
{
title
:
'用户
管理
'
,
title
:
'用户
列表
'
,
name
:
'users'
},
{
...
...
src/views/sys-permissions/user/index.vue
浏览文件 @
a9ae07d6
...
...
@@ -2,7 +2,7 @@
* @Author: xiejiang
* @Date: 2024-11-28 15:01:02
* @LastEditors: xiejiang
* @LastEditTime: 2024-12-0
5 15:03:09
* @LastEditTime: 2024-12-0
9 17:26:42
* @Description: 用户管理
* Copyright(c)2024 by 好老师教育科技有限公司 All right Reserved.
-->
...
...
@@ -22,10 +22,11 @@
:loading=
"loading"
placeholder=
"用户姓名/手机号码"
v-model=
"mobileOrName"
@
clear=
"handleClear"
@
on-search=
"handleSearch(searchParams)"
/></
template
>
<
template
#
header-right
>
<div
class=
"flex items-center justify-end gap-2"
>
<div
class=
"flex items-center justify-end gap-2"
v-if=
"buttonPms('user-add-btn')"
>
<t-button
shape=
"round"
theme=
"primary"
@
click=
"handelEdit(null)"
>
<template
#
icon
><AddIcon
/></
template
>
添加用户
</t-button
...
...
@@ -38,8 +39,8 @@
<
template
v-else
><operate-btn
v-if=
"row.status != 2"
content=
"启用"
@
click=
"handelStatus(row, 2)"
>
</operate-btn>
<operate-btn
v-if=
"row.status != 1"
content=
"详情"
@
click=
"handelDetail(row)"
>
</operate-btn>
<operate-btn
content=
"编辑"
@
click=
"handelEdit(row)"
>
</operate-btn>
<operate-btn
v-if=
"row.status == 2"
content=
"停用"
@
click=
"handelStatus(row,
1
)"
>
</operate-btn>
<operate-btn
v-if=
"buttonPms('user-edit-btn')"
content=
"编辑"
@
click=
"handelEdit(row)"
>
</operate-btn>
<operate-btn
v-if=
"row.status == 2"
content=
"停用"
@
click=
"handelStatus(row,
3
)"
>
</operate-btn>
<operate-btn
v-if=
"row.status != 2"
content=
"删除"
@
click=
"handelDel(row)"
></operate-btn
></
template
>
</template>
...
...
@@ -56,6 +57,7 @@ import { PrimaryTableCol, MessagePlugin } from 'tdesign-vue-next'
import
type
{
filterItemProp
}
from
'src/components/PageFilters/interface/index'
import
type
{
Pagination
}
from
'src/components/PageContainer/interface/index'
import
{
statusTxt
}
from
'@/utils/status'
import
{
buttonPms
}
from
'@/utils'
import
{
useBasic
}
from
'@/hooks/useBasic'
import
MessageBox
from
'@/utils/messageBox'
import
UserEdit
from
'./page/user-edit.vue'
...
...
@@ -75,7 +77,7 @@ onMounted(() => {
title
:
'用户管理'
}
])
getData
()
//
getData()
})
// 加载状态
...
...
@@ -112,7 +114,20 @@ const columns: PrimaryTableCol[] = [
},
{
title
:
'用户姓名'
,
colKey
:
'userName'
},
{
title
:
'手机号码'
,
colKey
:
'mobile'
},
{
title
:
'用户角色'
,
width
:
220
,
colKey
:
'roleNames'
},
{
title
:
'用户角色'
,
width
:
220
,
colKey
:
'roles'
,
ellipsis
:
true
,
cell
:
(
h
,
{
row
})
=>
{
const
roles
=
row
.
roles
||
[]
return
(
<
p
class
=
'ellipsis w-full'
>
<
span
>
{
roles
.
map
((
e
:
{
name
:
string
})
=>
e
.
name
).
join
(
';'
)
||
'-'
}
<
/span
>
<
/p
>
)
}
},
{
title
:
'状态'
,
colKey
:
'status'
,
...
...
@@ -126,7 +141,7 @@ const columns: PrimaryTableCol[] = [
}
},
{
title
:
'添加时间'
,
colKey
:
'inputTime'
},
{
title
:
'添加人'
,
colKey
:
'i
m
putUserName'
},
{
title
:
'添加人'
,
colKey
:
'i
n
putUserName'
},
{
title
:
'操作'
,
colKey
:
'operation'
,
fixed
:
'right'
,
width
:
220
}
]
...
...
@@ -158,6 +173,13 @@ const handleSearch = (params: Record<string, any>) => {
getData
()
}
// 清空搜索条件
const
handleClear
=
()
=>
{
mobileOrName
.
value
=
''
pagination
.
value
.
page
=
1
getData
()
}
// 处理分页
const
handlePage
=
(
pageInfo
:
Pagination
)
=>
{
pagination
.
value
=
{
...
pagination
.
value
,
...
pageInfo
}
...
...
@@ -212,7 +234,7 @@ const handelDel = (row: ResUserList) => {
dialog
.
update
({
confirmBtn
:
{
content
:
'确定'
,
loading
:
true
}
})
getUserOperate
({
userId
:
row
?.
userId
,
operateType
:
3
operateType
:
1
})
.
then
(()
=>
{
getData
()
...
...
src/views/sys-permissions/user/page/user-edit.vue
浏览文件 @
a9ae07d6
...
...
@@ -16,6 +16,7 @@
<t-form-item
label=
"手机号码"
name=
"mobile"
>
<t-input
v-model=
"formData.mobile"
maxlength=
"11"
@
input=
"v => (formData.mobile = v.replace(/[^0-9]/g, ''))"
placeholder=
"请输入手机号码"
>
...
...
@@ -27,7 +28,7 @@
</t-select>
</t-form-item>
<t-form-item
label=
"用户备注"
name=
"remark"
>
<t-textarea
maxlength=
"200"
v-model=
"formData.remark"
placeholder=
"请输入用户备注"
>
</t-textarea>
<t-textarea
:
maxlength=
"200"
v-model=
"formData.remark"
placeholder=
"请输入用户备注"
>
</t-textarea>
</t-form-item>
</t-form>
</Drawer>
...
...
@@ -97,11 +98,10 @@ const rules: FormProps['rules'] = {
],
mobile
:
[
{
required
:
true
,
validator
:
validateTelePhone
}
],
role
:
[
role
Ids
:
[
{
required
:
true
,
message
:
'请选择用户角色!'
,
...
...
@@ -119,10 +119,13 @@ const open = (val: ResUserList | null) => {
if
(
Object
.
prototype
.
hasOwnProperty
.
call
(
val
,
key
))
{
;(
formData
as
any
)[
key
]
=
val
[
key
]
}
const
roleIds
=
val
.
roles
||
[]
formData
.
roleIds
=
roleIds
.
map
((
item
:
{
id
:
string
})
=>
item
.
id
)
}
}
else
{
title
.
value
=
'新增用户'
}
getRoleListData
()
}
const
close
=
()
=>
{
formRef
.
value
?.
reset
()
...
...
@@ -155,18 +158,12 @@ const handleConfirm = () => {
const
emit
=
defineEmits
([
'success'
])
onMounted
(()
=>
{
getRoleListData
()
})
//
onMounted(() => {
//
getRoleListData()
//
})
defineExpose
({
open
,
close
})
</
script
>
<
style
lang=
"less"
scoped
>
:deep(.t-textarea__limit) {
display: none;
}
</
style
>
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论