fetch(modify):修复BUG
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 3m27s
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 3m27s
This commit is contained in:
@@ -183,6 +183,115 @@
|
||||
|
||||
<!-- 客户账号列表弹窗 -->
|
||||
<CustomerAccountDialog v-model="customerAccountDialogVisible" :shop-id="currentShopId" />
|
||||
|
||||
<!-- 店铺操作右键菜单 -->
|
||||
<ArtMenuRight
|
||||
ref="shopOperationMenuRef"
|
||||
:menu-items="shopOperationMenuItems"
|
||||
:menu-width="140"
|
||||
@select="handleShopOperationMenuSelect"
|
||||
/>
|
||||
|
||||
<!-- 店铺默认角色管理对话框 -->
|
||||
<ElDialog
|
||||
v-model="defaultRolesDialogVisible"
|
||||
:title="`设置默认角色 - ${currentShop?.shop_name || ''}`"
|
||||
width="800px"
|
||||
>
|
||||
<div v-loading="defaultRolesLoading">
|
||||
<!-- 当前默认角色列表 -->
|
||||
<div class="default-roles-section">
|
||||
<div class="section-header">
|
||||
<span>当前默认角色</span>
|
||||
<ElButton type="primary" @click="showAddRoleDialog">
|
||||
添加角色
|
||||
</ElButton>
|
||||
</div>
|
||||
<ElTable :data="currentDefaultRoles" border stripe style="margin-top: 12px">
|
||||
<ElTableColumn prop="role_name" label="角色名称" width="150" />
|
||||
<ElTableColumn prop="role_desc" label="角色描述" min-width="200" />
|
||||
<ElTableColumn prop="status" label="状态" width="80">
|
||||
<template #default="{ row }">
|
||||
<ElTag :type="row.status === CommonStatus.ENABLED ? 'success' : 'info'" size="small">
|
||||
{{ getStatusText(row.status) }}
|
||||
</ElTag>
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
<ElTableColumn label="操作" width="100" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<ElButton
|
||||
type="danger"
|
||||
text
|
||||
size="small"
|
||||
@click="handleDeleteDefaultRole(row)"
|
||||
>
|
||||
删除
|
||||
</ElButton>
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
<template #empty>
|
||||
<div style="padding: 20px 0; color: #909399;">
|
||||
暂无默认角色,请点击"添加角色"按钮进行配置
|
||||
</div>
|
||||
</template>
|
||||
</ElTable>
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<ElButton @click="defaultRolesDialogVisible = false">关闭</ElButton>
|
||||
</div>
|
||||
</template>
|
||||
</ElDialog>
|
||||
|
||||
<!-- 添加角色对话框 -->
|
||||
<ElDialog
|
||||
v-model="addRoleDialogVisible"
|
||||
title="添加默认角色"
|
||||
width="600px"
|
||||
append-to-body
|
||||
>
|
||||
<div v-loading="rolesLoading">
|
||||
<ElSelect
|
||||
v-model="selectedRoleIds"
|
||||
multiple
|
||||
filterable
|
||||
placeholder="请选择要添加的角色"
|
||||
style="width: 100%"
|
||||
>
|
||||
<ElOption
|
||||
v-for="role in availableRoles"
|
||||
:key="role.role_id"
|
||||
:label="role.role_name"
|
||||
:value="role.role_id"
|
||||
:disabled="isRoleAlreadyAssigned(role.role_id)"
|
||||
>
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; width: 100%;">
|
||||
<div style="display: flex; gap: 8px; align-items: center;">
|
||||
<span>{{ role.role_name }}</span>
|
||||
<ElTag :type="role.role_type === 1 ? 'primary' : 'success'" size="small">
|
||||
{{ role.role_type === 1 ? '平台角色' : '客户角色' }}
|
||||
</ElTag>
|
||||
</div>
|
||||
<span v-if="isRoleAlreadyAssigned(role.role_id)" style="color: #909399; font-size: 12px;">
|
||||
已添加
|
||||
</span>
|
||||
</div>
|
||||
</ElOption>
|
||||
</ElSelect>
|
||||
<div style="margin-top: 8px; color: #909399; font-size: 12px;">
|
||||
支持多选,已添加的角色将显示为禁用状态
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<ElButton @click="addRoleDialogVisible = false">取消</ElButton>
|
||||
<ElButton type="primary" @click="handleAddDefaultRoles" :loading="addRoleLoading">
|
||||
确定
|
||||
</ElButton>
|
||||
</div>
|
||||
</template>
|
||||
</ElDialog>
|
||||
</ElCard>
|
||||
</div>
|
||||
</ArtTableFullScreen>
|
||||
@@ -202,10 +311,13 @@
|
||||
import type { FormRules } from 'element-plus'
|
||||
import { useCheckedColumns } from '@/composables/useCheckedColumns'
|
||||
import ArtButtonTable from '@/components/core/forms/ArtButtonTable.vue'
|
||||
import ArtMenuRight from '@/components/core/others/ArtMenuRight.vue'
|
||||
import type { MenuItemType } from '@/components/core/others/ArtMenuRight.vue'
|
||||
import CustomerAccountDialog from '@/components/business/CustomerAccountDialog.vue'
|
||||
import { ShopService } from '@/api/modules'
|
||||
import { ShopService, RoleService } from '@/api/modules'
|
||||
import type { SearchFormItem } from '@/types'
|
||||
import type { ShopResponse } from '@/types/api'
|
||||
import type { ShopResponse, ShopRoleResponse } from '@/types/api'
|
||||
import { RoleType } from '@/types/api'
|
||||
import { formatDateTime } from '@/utils/business/format'
|
||||
import { CommonStatus, getStatusText, STATUS_SELECT_OPTIONS } from '@/config/constants'
|
||||
|
||||
@@ -221,6 +333,21 @@
|
||||
const parentShopList = ref<ShopResponse[]>([])
|
||||
const searchParentShopList = ref<ShopResponse[]>([])
|
||||
|
||||
// 默认角色管理相关状态
|
||||
const defaultRolesDialogVisible = ref(false)
|
||||
const addRoleDialogVisible = ref(false)
|
||||
const defaultRolesLoading = ref(false)
|
||||
const rolesLoading = ref(false)
|
||||
const addRoleLoading = ref(false)
|
||||
const currentShop = ref<ShopResponse | null>(null)
|
||||
const currentDefaultRoles = ref<ShopRoleResponse[]>([])
|
||||
const availableRoles = ref<ShopRoleResponse[]>([])
|
||||
const selectedRoleIds = ref<number[]>([])
|
||||
|
||||
// 右键菜单
|
||||
const shopOperationMenuRef = ref<InstanceType<typeof ArtMenuRight>>()
|
||||
const currentOperatingShop = ref<ShopResponse | null>(null)
|
||||
|
||||
// 定义表单搜索初始值
|
||||
const initialSearchState = {
|
||||
shop_name: '',
|
||||
@@ -476,7 +603,7 @@
|
||||
{
|
||||
prop: 'operation',
|
||||
label: '操作',
|
||||
width: 220,
|
||||
width: 200,
|
||||
fixed: 'right',
|
||||
formatter: (row: ShopResponse) => {
|
||||
return h('div', { style: 'display: flex; gap: 8px;' }, [
|
||||
@@ -485,12 +612,8 @@
|
||||
onClick: () => viewCustomerAccounts(row)
|
||||
}),
|
||||
h(ArtButtonTable, {
|
||||
type: 'edit',
|
||||
onClick: () => showDialog('edit', row)
|
||||
}),
|
||||
h(ArtButtonTable, {
|
||||
type: 'delete',
|
||||
onClick: () => deleteShop(row)
|
||||
text: '更多操作',
|
||||
onContextmenu: (e: MouseEvent) => showShopOperationMenu(e, row)
|
||||
})
|
||||
])
|
||||
}
|
||||
@@ -750,6 +873,47 @@
|
||||
customerAccountDialogVisible.value = true
|
||||
}
|
||||
|
||||
// 店铺操作菜单项配置
|
||||
const shopOperationMenuItems = computed((): MenuItemType[] => [
|
||||
{
|
||||
key: 'defaultRoles',
|
||||
label: '默认角色'
|
||||
},
|
||||
{
|
||||
key: 'edit',
|
||||
label: '编辑'
|
||||
},
|
||||
{
|
||||
key: 'delete',
|
||||
label: '删除'
|
||||
}
|
||||
])
|
||||
|
||||
// 显示店铺操作右键菜单
|
||||
const showShopOperationMenu = (e: MouseEvent, row: ShopResponse) => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
currentOperatingShop.value = row
|
||||
shopOperationMenuRef.value?.show(e)
|
||||
}
|
||||
|
||||
// 处理店铺操作菜单选择
|
||||
const handleShopOperationMenuSelect = (item: MenuItemType) => {
|
||||
if (!currentOperatingShop.value) return
|
||||
|
||||
switch (item.key) {
|
||||
case 'defaultRoles':
|
||||
showDefaultRolesDialog(currentOperatingShop.value)
|
||||
break
|
||||
case 'edit':
|
||||
showDialog('edit', currentOperatingShop.value)
|
||||
break
|
||||
case 'delete':
|
||||
deleteShop(currentOperatingShop.value)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 状态切换
|
||||
const handleStatusChange = async (row: ShopResponse, newStatus: number) => {
|
||||
const oldStatus = row.status
|
||||
@@ -767,10 +931,144 @@
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
|
||||
// ========== 默认角色管理功能 ==========
|
||||
|
||||
// 显示默认角色管理对话框
|
||||
const showDefaultRolesDialog = async (row: ShopResponse) => {
|
||||
currentShop.value = row
|
||||
defaultRolesDialogVisible.value = true
|
||||
await loadShopDefaultRoles(row.id)
|
||||
}
|
||||
|
||||
// 加载店铺默认角色列表
|
||||
const loadShopDefaultRoles = async (shopId: number) => {
|
||||
defaultRolesLoading.value = true
|
||||
try {
|
||||
const res = await ShopService.getShopRoles(shopId)
|
||||
if (res.code === 0) {
|
||||
currentDefaultRoles.value = res.data.roles || []
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取店铺默认角色失败:', error)
|
||||
ElMessage.error('获取店铺默认角色失败')
|
||||
} finally {
|
||||
defaultRolesLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 显示添加角色对话框
|
||||
const showAddRoleDialog = async () => {
|
||||
addRoleDialogVisible.value = true
|
||||
selectedRoleIds.value = []
|
||||
await loadAvailableRoles()
|
||||
}
|
||||
|
||||
// 加载可用角色列表
|
||||
const loadAvailableRoles = async () => {
|
||||
rolesLoading.value = true
|
||||
try {
|
||||
const res = await RoleService.getRoles({
|
||||
page: 1,
|
||||
page_size: 9999,
|
||||
status: 1 // RoleStatus.ENABLED
|
||||
})
|
||||
if (res.code === 0) {
|
||||
// 将 PlatformRole 转换为与 ShopRoleResponse 兼容的格式,同时保留 role_type
|
||||
availableRoles.value = (res.data.items || []).map((role) => ({
|
||||
...role,
|
||||
role_id: role.ID,
|
||||
role_name: role.role_name,
|
||||
role_desc: role.role_desc,
|
||||
role_type: role.role_type, // 保留角色类型用于显示
|
||||
shop_id: 0 // 这个值在可用角色列表中不使用
|
||||
}))
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取角色列表失败:', error)
|
||||
ElMessage.error('获取角色列表失败')
|
||||
} finally {
|
||||
rolesLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 判断角色是否已分配
|
||||
const isRoleAlreadyAssigned = (roleId: number) => {
|
||||
return currentDefaultRoles.value.some((r) => r.role_id === roleId)
|
||||
}
|
||||
|
||||
// 添加默认角色
|
||||
const handleAddDefaultRoles = async () => {
|
||||
if (selectedRoleIds.value.length === 0) {
|
||||
ElMessage.warning('请至少选择一个角色')
|
||||
return
|
||||
}
|
||||
|
||||
if (!currentShop.value) {
|
||||
ElMessage.error('店铺信息异常')
|
||||
return
|
||||
}
|
||||
|
||||
addRoleLoading.value = true
|
||||
try {
|
||||
const res = await ShopService.assignShopRoles(currentShop.value.id, {
|
||||
role_ids: selectedRoleIds.value
|
||||
})
|
||||
if (res.code === 0) {
|
||||
ElMessage.success('添加默认角色成功')
|
||||
addRoleDialogVisible.value = false
|
||||
// 刷新默认角色列表
|
||||
await loadShopDefaultRoles(currentShop.value.id)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('添加默认角色失败:', error)
|
||||
} finally {
|
||||
addRoleLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 删除默认角色
|
||||
const handleDeleteDefaultRole = (role: ShopRoleResponse) => {
|
||||
ElMessageBox.confirm(`确定要删除默认角色 "${role.role_name}" 吗?`, '删除默认角色', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
.then(async () => {
|
||||
if (!currentShop.value) {
|
||||
ElMessage.error('店铺信息异常')
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
await ShopService.deleteShopRole(currentShop.value.id, role.role_id)
|
||||
ElMessage.success('删除成功')
|
||||
// 刷新默认角色列表
|
||||
await loadShopDefaultRoles(currentShop.value.id)
|
||||
} catch (error) {
|
||||
console.error('删除默认角色失败:', error)
|
||||
ElMessage.error('删除默认角色失败')
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
// 用户取消删除
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.shop-page {
|
||||
// 店铺管理页面样式
|
||||
}
|
||||
|
||||
.default-roles-section {
|
||||
.section-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #303133;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user