This commit is contained in:
@@ -86,9 +86,18 @@
|
|||||||
<span class="dialog-title">分配角色</span>
|
<span class="dialog-title">分配角色</span>
|
||||||
<div class="account-info">
|
<div class="account-info">
|
||||||
<span class="account-name">{{ currentAccountName }}</span>
|
<span class="account-name">{{ currentAccountName }}</span>
|
||||||
|
<ElTag v-if="currentAccountType === 1" type="danger" size="small" style="margin-left: 8px">
|
||||||
|
超级管理员不能分配角色
|
||||||
|
</ElTag>
|
||||||
|
<ElTag v-if="currentAccountType === 2" type="info" size="small" style="margin-left: 8px">
|
||||||
|
平台用户只能分配一个平台角色
|
||||||
|
</ElTag>
|
||||||
<ElTag v-if="currentAccountType === 3" type="warning" size="small" style="margin-left: 8px">
|
<ElTag v-if="currentAccountType === 3" type="warning" size="small" style="margin-left: 8px">
|
||||||
代理账号只能分配一个客户角色
|
代理账号只能分配一个客户角色
|
||||||
</ElTag>
|
</ElTag>
|
||||||
|
<ElTag v-if="currentAccountType === 4" type="warning" size="small" style="margin-left: 8px">
|
||||||
|
企业账号只能分配一个客户角色
|
||||||
|
</ElTag>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -549,9 +558,15 @@
|
|||||||
let roles = allRoles.value
|
let roles = allRoles.value
|
||||||
|
|
||||||
// 根据账号类型过滤角色
|
// 根据账号类型过滤角色
|
||||||
if (currentAccountType.value === 3) {
|
if (currentAccountType.value === 1) {
|
||||||
|
// 超级管理员:不能分配任何角色
|
||||||
|
return []
|
||||||
|
} else if (currentAccountType.value === 3) {
|
||||||
// 代理账号:只显示客户角色
|
// 代理账号:只显示客户角色
|
||||||
roles = roles.filter((role) => role.role_type === 2)
|
roles = roles.filter((role) => role.role_type === 2)
|
||||||
|
} else if (currentAccountType.value === 4) {
|
||||||
|
// 企业账号:只显示客户角色
|
||||||
|
roles = roles.filter((role) => role.role_type === 2)
|
||||||
} else if (currentAccountType.value === 2) {
|
} else if (currentAccountType.value === 2) {
|
||||||
// 平台用户:只显示平台角色
|
// 平台用户:只显示平台角色
|
||||||
roles = roles.filter((role) => role.role_type === 1)
|
roles = roles.filter((role) => role.role_type === 1)
|
||||||
@@ -605,21 +620,15 @@
|
|||||||
if (rolesToAdd.value.length === 0) return
|
if (rolesToAdd.value.length === 0) return
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let newRoles: number[]
|
// 所有账号只能分配一个角色
|
||||||
|
if (rolesToAdd.value.length > 1) {
|
||||||
// 代理账号只能分配一个角色,会覆盖之前的角色
|
ElMessage.warning('只能分配一个角色')
|
||||||
if (currentAccountType.value === 3) {
|
return
|
||||||
if (rolesToAdd.value.length > 1) {
|
|
||||||
ElMessage.warning('代理账号只能分配一个角色')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// 只保留新选择的一个角色
|
|
||||||
newRoles = rolesToAdd.value
|
|
||||||
} else {
|
|
||||||
// 其他账号类型可以分配多个角色
|
|
||||||
newRoles = [...new Set([...selectedRoles.value, ...rolesToAdd.value])]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 新角色会替换之前的角色
|
||||||
|
const newRoles = rolesToAdd.value
|
||||||
|
|
||||||
await AccountService.assignRolesToAccount(currentAccountId.value, newRoles)
|
await AccountService.assignRolesToAccount(currentAccountId.value, newRoles)
|
||||||
|
|
||||||
selectedRoles.value = newRoles
|
selectedRoles.value = newRoles
|
||||||
|
|||||||
@@ -458,7 +458,7 @@
|
|||||||
{
|
{
|
||||||
prop: 'operation',
|
prop: 'operation',
|
||||||
label: '操作',
|
label: '操作',
|
||||||
width: 280,
|
width: 190,
|
||||||
fixed: 'right',
|
fixed: 'right',
|
||||||
formatter: (row: EnterpriseItem) => {
|
formatter: (row: EnterpriseItem) => {
|
||||||
const buttons = []
|
const buttons = []
|
||||||
@@ -481,16 +481,6 @@
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 只要有编辑、修改密码权限之一,就显示更多操作按钮
|
|
||||||
if (hasAuth('enterprise_customer:edit') || hasAuth('enterprise_customer:update_pwd')) {
|
|
||||||
buttons.push(
|
|
||||||
h(ArtButtonTable, {
|
|
||||||
text: '更多操作',
|
|
||||||
onContextmenu: (e: MouseEvent) => showEnterpriseOperationMenu(e, row)
|
|
||||||
})
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return h('div', { style: 'display: flex; gap: 8px;' }, buttons)
|
return h('div', { style: 'display: flex; gap: 8px;' }, buttons)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -358,7 +358,10 @@
|
|||||||
</template>
|
</template>
|
||||||
</ElTableColumn>
|
</ElTableColumn>
|
||||||
</ElTable>
|
</ElTable>
|
||||||
<div v-if="deviceCards.length === 0" style="text-align: center; padding: 20px; color: #909399">
|
<div
|
||||||
|
v-if="deviceCards.length === 0"
|
||||||
|
style="text-align: center; padding: 20px; color: #909399"
|
||||||
|
>
|
||||||
暂无绑定的卡片
|
暂无绑定的卡片
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -374,7 +377,12 @@
|
|||||||
|
|
||||||
<!-- 绑定卡弹窗 -->
|
<!-- 绑定卡弹窗 -->
|
||||||
<ElDialog v-model="bindCardDialogVisible" title="绑定卡到设备" width="500px">
|
<ElDialog v-model="bindCardDialogVisible" title="绑定卡到设备" width="500px">
|
||||||
<ElForm ref="bindCardFormRef" :model="bindCardForm" :rules="bindCardRules" label-width="100px">
|
<ElForm
|
||||||
|
ref="bindCardFormRef"
|
||||||
|
:model="bindCardForm"
|
||||||
|
:rules="bindCardRules"
|
||||||
|
label-width="100px"
|
||||||
|
>
|
||||||
<ElFormItem label="IoT卡" prop="iot_card_id">
|
<ElFormItem label="IoT卡" prop="iot_card_id">
|
||||||
<ElSelect
|
<ElSelect
|
||||||
v-model="bindCardForm.iot_card_id"
|
v-model="bindCardForm.iot_card_id"
|
||||||
@@ -396,7 +404,11 @@
|
|||||||
</ElSelect>
|
</ElSelect>
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
<ElFormItem label="插槽位置" prop="slot_position">
|
<ElFormItem label="插槽位置" prop="slot_position">
|
||||||
<ElSelect v-model="bindCardForm.slot_position" placeholder="请选择插槽位置" style="width: 100%">
|
<ElSelect
|
||||||
|
v-model="bindCardForm.slot_position"
|
||||||
|
placeholder="请选择插槽位置"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
<ElOption
|
<ElOption
|
||||||
v-for="i in currentDeviceDetail?.max_sim_slots || 4"
|
v-for="i in currentDeviceDetail?.max_sim_slots || 4"
|
||||||
:key="i"
|
:key="i"
|
||||||
@@ -903,7 +915,9 @@
|
|||||||
// 重新加载卡列表
|
// 重新加载卡列表
|
||||||
await loadDeviceCards(currentDeviceDetail.value.id)
|
await loadDeviceCards(currentDeviceDetail.value.id)
|
||||||
// 刷新设备详情以更新绑定卡数量
|
// 刷新设备详情以更新绑定卡数量
|
||||||
const detailRes = await DeviceService.getDeviceByImei(currentDeviceDetail.value.device_no)
|
const detailRes = await DeviceService.getDeviceByImei(
|
||||||
|
currentDeviceDetail.value.device_no
|
||||||
|
)
|
||||||
if (detailRes.code === 0 && detailRes.data) {
|
if (detailRes.code === 0 && detailRes.data) {
|
||||||
currentDeviceDetail.value = detailRes.data
|
currentDeviceDetail.value = detailRes.data
|
||||||
}
|
}
|
||||||
@@ -929,10 +943,7 @@
|
|||||||
})
|
})
|
||||||
.then(async () => {
|
.then(async () => {
|
||||||
try {
|
try {
|
||||||
const res = await DeviceService.unbindCard(
|
const res = await DeviceService.unbindCard(currentDeviceDetail.value.id, row.iot_card_id)
|
||||||
currentDeviceDetail.value.id,
|
|
||||||
row.iot_card_id
|
|
||||||
)
|
|
||||||
if (res.code === 0) {
|
if (res.code === 0) {
|
||||||
ElMessage.success('解绑成功')
|
ElMessage.success('解绑成功')
|
||||||
// 重新加载卡列表
|
// 重新加载卡列表
|
||||||
@@ -1070,23 +1081,6 @@
|
|||||||
label: '创建时间',
|
label: '创建时间',
|
||||||
width: 180,
|
width: 180,
|
||||||
formatter: (row: Device) => formatDateTime(row.created_at)
|
formatter: (row: Device) => formatDateTime(row.created_at)
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'operation',
|
|
||||||
label: '操作',
|
|
||||||
width: 120,
|
|
||||||
fixed: 'right',
|
|
||||||
formatter: (row: Device) => {
|
|
||||||
// Show "更多操作" only if user has at least one operation permission
|
|
||||||
const hasAnyOperationPermission = hasAuth('devices:delete') || hasAuth('devices:look_binding')
|
|
||||||
if (hasAnyOperationPermission) {
|
|
||||||
return h(ArtButtonTable, {
|
|
||||||
text: '更多操作',
|
|
||||||
onContextmenu: (e: MouseEvent) => showDeviceOperationMenu(e, row.device_no)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|
||||||
@@ -1105,8 +1099,8 @@
|
|||||||
try {
|
try {
|
||||||
const res = await ShopService.getShops({
|
const res = await ShopService.getShops({
|
||||||
page: 1,
|
page: 1,
|
||||||
page_size: 9999, // 获取所有数据用于构建树形结构
|
page_size: 9999, // 获取所有数据用于构建树形结构
|
||||||
status: 1 // 只获取启用的店铺
|
status: 1 // 只获取启用的店铺
|
||||||
})
|
})
|
||||||
if (res.code === 0) {
|
if (res.code === 0) {
|
||||||
shopTreeData.value = buildShopTree(res.data.items || [])
|
shopTreeData.value = buildShopTree(res.data.items || [])
|
||||||
@@ -1349,7 +1343,7 @@
|
|||||||
const params: any = {
|
const params: any = {
|
||||||
page: 1,
|
page: 1,
|
||||||
page_size: 20,
|
page_size: 20,
|
||||||
status: 1 // 只获取启用的
|
status: 1 // 只获取启用的
|
||||||
}
|
}
|
||||||
if (seriesName) {
|
if (seriesName) {
|
||||||
params.series_name = seriesName
|
params.series_name = seriesName
|
||||||
@@ -1445,7 +1439,7 @@
|
|||||||
|
|
||||||
// 通过设备号查看卡片
|
// 通过设备号查看卡片
|
||||||
const handleViewCardsByDeviceNo = (deviceNo: string) => {
|
const handleViewCardsByDeviceNo = (deviceNo: string) => {
|
||||||
const device = deviceList.value.find(d => d.device_no === deviceNo)
|
const device = deviceList.value.find((d) => d.device_no === deviceNo)
|
||||||
if (device) {
|
if (device) {
|
||||||
handleViewCards(device)
|
handleViewCards(device)
|
||||||
} else {
|
} else {
|
||||||
@@ -1456,7 +1450,7 @@
|
|||||||
// 通过设备号删除设备
|
// 通过设备号删除设备
|
||||||
const handleDeleteDeviceByNo = async (deviceNo: string) => {
|
const handleDeleteDeviceByNo = async (deviceNo: string) => {
|
||||||
// 先根据设备号找到设备对象
|
// 先根据设备号找到设备对象
|
||||||
const device = deviceList.value.find(d => d.device_no === deviceNo)
|
const device = deviceList.value.find((d) => d.device_no === deviceNo)
|
||||||
if (device) {
|
if (device) {
|
||||||
deleteDevice(device)
|
deleteDevice(device)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1096,18 +1096,6 @@
|
|||||||
label: '创建时间',
|
label: '创建时间',
|
||||||
width: 180,
|
width: 180,
|
||||||
formatter: (row: StandaloneIotCard) => formatDateTime(row.created_at)
|
formatter: (row: StandaloneIotCard) => formatDateTime(row.created_at)
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'operation',
|
|
||||||
label: '操作',
|
|
||||||
width: 120,
|
|
||||||
fixed: 'right',
|
|
||||||
formatter: (row: StandaloneIotCard) => {
|
|
||||||
return h(ArtButtonTable, {
|
|
||||||
text: '更多操作',
|
|
||||||
onContextmenu: (e: MouseEvent) => showCardOperationMenu(e, row.iccid)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|||||||
@@ -37,12 +37,36 @@
|
|||||||
:marginTop="10"
|
:marginTop="10"
|
||||||
@size-change="handleSizeChange"
|
@size-change="handleSizeChange"
|
||||||
@current-change="handleCurrentChange"
|
@current-change="handleCurrentChange"
|
||||||
|
@row-contextmenu="handleRowContextMenu"
|
||||||
>
|
>
|
||||||
<template #default>
|
<template #default>
|
||||||
<ElTableColumn v-for="col in columns" :key="col.prop || col.type" v-bind="col" />
|
<ElTableColumn v-for="col in columns" :key="col.prop || col.type" v-bind="col" />
|
||||||
</template>
|
</template>
|
||||||
</ArtTable>
|
</ArtTable>
|
||||||
|
|
||||||
|
<!-- 右键菜单 -->
|
||||||
|
<div
|
||||||
|
v-if="contextMenuVisible"
|
||||||
|
:style="{
|
||||||
|
position: 'fixed',
|
||||||
|
left: contextMenuPosition.x + 'px',
|
||||||
|
top: contextMenuPosition.y + 'px',
|
||||||
|
zIndex: 9999
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<ElCard shadow="always" class="context-menu">
|
||||||
|
<div class="context-menu-item" @click="handleViewDetail(contextMenuRow)" v-if="hasAuth('package_series:detail')">
|
||||||
|
<span>详情</span>
|
||||||
|
</div>
|
||||||
|
<div class="context-menu-item" @click="showDialog('edit', contextMenuRow)" v-if="hasAuth('package_series:edit')">
|
||||||
|
<span>编辑</span>
|
||||||
|
</div>
|
||||||
|
<div class="context-menu-item danger" @click="deleteSeries(contextMenuRow)" v-if="hasAuth('package_series:delete')">
|
||||||
|
<span>删除</span>
|
||||||
|
</div>
|
||||||
|
</ElCard>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 新增/编辑对话框 -->
|
<!-- 新增/编辑对话框 -->
|
||||||
<ElDialog
|
<ElDialog
|
||||||
v-model="dialogVisible"
|
v-model="dialogVisible"
|
||||||
@@ -386,6 +410,11 @@
|
|||||||
const tableRef = ref()
|
const tableRef = ref()
|
||||||
const formRef = ref<FormInstance>()
|
const formRef = ref<FormInstance>()
|
||||||
|
|
||||||
|
// 右键菜单状态
|
||||||
|
const contextMenuVisible = ref(false)
|
||||||
|
const contextMenuPosition = reactive({ x: 0, y: 0 })
|
||||||
|
const contextMenuRow = ref<PackageSeriesResponse | null>(null)
|
||||||
|
|
||||||
// 搜索表单初始值
|
// 搜索表单初始值
|
||||||
const initialSearchState = {
|
const initialSearchState = {
|
||||||
series_name: '',
|
series_name: '',
|
||||||
@@ -456,8 +485,7 @@
|
|||||||
{ label: '强充计算类型', prop: 'force_calc_type' },
|
{ label: '强充计算类型', prop: 'force_calc_type' },
|
||||||
{ label: '时效类型', prop: 'validity_type' },
|
{ label: '时效类型', prop: 'validity_type' },
|
||||||
{ label: '状态', prop: 'status' },
|
{ label: '状态', prop: 'status' },
|
||||||
{ label: '创建时间', prop: 'created_at' },
|
{ label: '创建时间', prop: 'created_at' }
|
||||||
{ label: '操作', prop: 'operation' }
|
|
||||||
]
|
]
|
||||||
|
|
||||||
// 表单验证规则
|
// 表单验证规则
|
||||||
@@ -675,50 +703,34 @@
|
|||||||
label: '创建时间',
|
label: '创建时间',
|
||||||
width: 180,
|
width: 180,
|
||||||
formatter: (row: PackageSeriesResponse) => formatDateTime(row.created_at)
|
formatter: (row: PackageSeriesResponse) => formatDateTime(row.created_at)
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'operation',
|
|
||||||
label: '操作',
|
|
||||||
width: 220,
|
|
||||||
fixed: 'right',
|
|
||||||
formatter: (row: PackageSeriesResponse) => {
|
|
||||||
const buttons = []
|
|
||||||
|
|
||||||
// 详情按钮
|
|
||||||
buttons.push(
|
|
||||||
h(ArtButtonTable, {
|
|
||||||
text: '详情',
|
|
||||||
onClick: () => handleViewDetail(row)
|
|
||||||
})
|
|
||||||
)
|
|
||||||
|
|
||||||
if (hasAuth('package_series:edit')) {
|
|
||||||
buttons.push(
|
|
||||||
h(ArtButtonTable, {
|
|
||||||
text: '编辑',
|
|
||||||
onClick: () => showDialog('edit', row)
|
|
||||||
})
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasAuth('package_series:delete')) {
|
|
||||||
buttons.push(
|
|
||||||
h(ArtButtonTable, {
|
|
||||||
text: '删除',
|
|
||||||
onClick: () => deleteSeries(row)
|
|
||||||
})
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return h('div', { style: 'display: flex; gap: 8px;' }, buttons)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getTableData()
|
getTableData()
|
||||||
|
// 添加全局点击事件监听,关闭右键菜单
|
||||||
|
document.addEventListener('click', closeContextMenu)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
// 移除全局点击事件监听
|
||||||
|
document.removeEventListener('click', closeContextMenu)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 处理右键菜单
|
||||||
|
const handleRowContextMenu = (row: PackageSeriesResponse, column: any, event: MouseEvent) => {
|
||||||
|
event.preventDefault()
|
||||||
|
contextMenuRow.value = row
|
||||||
|
contextMenuPosition.x = event.clientX
|
||||||
|
contextMenuPosition.y = event.clientY
|
||||||
|
contextMenuVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭右键菜单
|
||||||
|
const closeContextMenu = () => {
|
||||||
|
contextMenuVisible.value = false
|
||||||
|
}
|
||||||
|
|
||||||
// 获取套餐系列列表
|
// 获取套餐系列列表
|
||||||
const getTableData = async () => {
|
const getTableData = async () => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
@@ -1046,4 +1058,35 @@
|
|||||||
.dialog-footer {
|
.dialog-footer {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.context-menu {
|
||||||
|
min-width: 120px;
|
||||||
|
padding: 4px 0;
|
||||||
|
background: white;
|
||||||
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||||
|
|
||||||
|
:deep(.el-card__body) {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.context-menu-item {
|
||||||
|
padding: 10px 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.2s;
|
||||||
|
font-size: 14px;
|
||||||
|
color: var(--el-text-color-primary);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--el-fill-color-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.danger {
|
||||||
|
color: var(--el-color-danger);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--el-color-danger-light-9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -181,7 +181,9 @@
|
|||||||
:label="role.role_name"
|
:label="role.role_name"
|
||||||
:value="role.ID"
|
:value="role.ID"
|
||||||
>
|
>
|
||||||
<div style="display: flex; justify-content: space-between; align-items: center;">
|
<div
|
||||||
|
style="display: flex; justify-content: space-between; align-items: center"
|
||||||
|
>
|
||||||
<span>{{ role.role_name }}</span>
|
<span>{{ role.role_name }}</span>
|
||||||
<ElTag type="success" size="small">客户角色</ElTag>
|
<ElTag type="success" size="small">客户角色</ElTag>
|
||||||
</div>
|
</div>
|
||||||
@@ -623,7 +625,7 @@
|
|||||||
{
|
{
|
||||||
prop: 'operation',
|
prop: 'operation',
|
||||||
label: '操作',
|
label: '操作',
|
||||||
width: 200,
|
width: 110,
|
||||||
fixed: 'right',
|
fixed: 'right',
|
||||||
formatter: (row: ShopResponse) => {
|
formatter: (row: ShopResponse) => {
|
||||||
const buttons = []
|
const buttons = []
|
||||||
@@ -637,16 +639,6 @@
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 只要有编辑或删除权限之一,就显示更多操作按钮
|
|
||||||
if (hasAuth('shop:edit') || hasAuth('shop:delete')) {
|
|
||||||
buttons.push(
|
|
||||||
h(ArtButtonTable, {
|
|
||||||
text: '更多操作',
|
|
||||||
onContextmenu: (e: MouseEvent) => showShopOperationMenu(e, row)
|
|
||||||
})
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return h('div', { style: 'display: flex; gap: 8px;' }, buttons)
|
return h('div', { style: 'display: flex; gap: 8px;' }, buttons)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -855,9 +847,7 @@
|
|||||||
{ len: 11, message: '手机号必须为 11 位', trigger: 'blur' },
|
{ len: 11, message: '手机号必须为 11 位', trigger: 'blur' },
|
||||||
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号格式', trigger: 'blur' }
|
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号格式', trigger: 'blur' }
|
||||||
],
|
],
|
||||||
default_role_id: [
|
default_role_id: [{ required: true, message: '请选择默认角色', trigger: 'blur' }]
|
||||||
{ required: true, message: '请选择默认角色', trigger: 'blur' }
|
|
||||||
]
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// 提交表单
|
// 提交表单
|
||||||
@@ -1048,9 +1038,8 @@
|
|||||||
const showAddRoleDialog = async () => {
|
const showAddRoleDialog = async () => {
|
||||||
addRoleDialogVisible.value = true
|
addRoleDialogVisible.value = true
|
||||||
// 如果已有默认角色,预选第一个
|
// 如果已有默认角色,预选第一个
|
||||||
selectedRoleId.value = currentDefaultRoles.value.length > 0
|
selectedRoleId.value =
|
||||||
? currentDefaultRoles.value[0].role_id
|
currentDefaultRoles.value.length > 0 ? currentDefaultRoles.value[0].role_id : undefined
|
||||||
: undefined
|
|
||||||
await loadAvailableRoles()
|
await loadAvailableRoles()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -734,15 +734,15 @@
|
|||||||
const getLeftCheckedKeysWithHalf = (): number[] => {
|
const getLeftCheckedKeysWithHalf = (): number[] => {
|
||||||
if (!leftTreeRef.value) return []
|
if (!leftTreeRef.value) return []
|
||||||
const checkedKeys = leftTreeRef.value.getCheckedKeys(false)
|
const checkedKeys = leftTreeRef.value.getCheckedKeys(false)
|
||||||
const parentIds = new Set<number>()
|
const allIds = new Set<number>(checkedKeys)
|
||||||
|
|
||||||
// 为每个勾选的节点找到所有父节点
|
// 为每个勾选的节点找到所有父节点
|
||||||
checkedKeys.forEach((key: number) => {
|
checkedKeys.forEach((key: number) => {
|
||||||
const parents = getParentNodeIds(key)
|
const parents = getParentNodeIds(key)
|
||||||
parents.forEach(parentId => parentIds.add(parentId))
|
parents.forEach(parentId => allIds.add(parentId))
|
||||||
})
|
})
|
||||||
|
|
||||||
return [...checkedKeys, ...Array.from(parentIds)]
|
return Array.from(allIds)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加权限
|
// 添加权限
|
||||||
|
|||||||
Reference in New Issue
Block a user