fetch(modify):修复BUG
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 3m27s

This commit is contained in:
sexygoat
2026-02-03 14:39:45 +08:00
parent 2c6fe4375b
commit de9753f42d
28 changed files with 4344 additions and 5092 deletions

View File

@@ -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>