feat: 代理商注册列表
All checks were successful
构建并部署前端到测试环境 / deploy (push) Successful in 55s

This commit is contained in:
luo
2026-09-21 18:07:36 +08:00
parent c5d7a260d0
commit c136f68ab8
34 changed files with 1112 additions and 142 deletions

View File

@@ -3,7 +3,13 @@
*/
import { BaseService } from '../BaseService'
import type { BaseResponse } from '@/types/api'
import type {
AgentDistributionRegistrationPageResult,
AgentDistributionRegistrationQueryParams,
AgentDistributionRegistrationItem,
BaseResponse,
RecoverAgentDistributionRegistrationResponse
} from '@/types/api'
/**
* 发送短信验证码请求参数
@@ -71,4 +77,32 @@ export class AgentDistributionService extends BaseService {
{ requestOptions: { withToken: false } }
)
}
/** 查询后台代理注册申请列表 */
static getRegistrationApplications(
params?: AgentDistributionRegistrationQueryParams
): Promise<BaseResponse<AgentDistributionRegistrationPageResult>> {
return this.get<BaseResponse<AgentDistributionRegistrationPageResult>>(
'/api/admin/agent-distribution-registrations',
params
)
}
/** 查询后台代理注册申请详情 */
static getRegistrationApplicationDetail(
id: number
): Promise<BaseResponse<AgentDistributionRegistrationItem>> {
return this.getOne<AgentDistributionRegistrationItem>(
`/api/admin/agent-distribution-registrations/${id}`
)
}
/** 恢复代理注册原审批提交 */
static recoverRegistrationApproval(
id: number
): Promise<BaseResponse<RecoverAgentDistributionRegistrationResponse>> {
return this.post<BaseResponse<RecoverAgentDistributionRegistrationResponse>>(
`/api/admin/agent-distribution-registrations/${id}/recover-approval`
)
}
}

View File

@@ -25,8 +25,18 @@ export const AUGUST_PERMISSIONS = {
unbindImportCreate: 'phone_asset_association:unbind_import_create',
unbindImportDetail: 'phone_asset_association:unbind_import_detail'
},
shop: {
listView: 'shop:list_view',
detailView: 'shop:detail_view'
},
agentDistributionRegistration: {
list: 'agent_distribution_registration:list',
detail: 'agent_distribution_registration:detail',
recoverApproval: 'agent_distribution_registration:recover_approval'
},
h5PopupConfiguration: {
list: 'h5_popup_configuration:list',
detail: 'h5_popup_configuration:detail',
create: 'h5_popup_configuration:create',
update: 'h5_popup_configuration:update',
enable: 'h5_popup_configuration:enable',
@@ -36,9 +46,39 @@ export const AUGUST_PERMISSIONS = {
rulesView: 'package_traffic_alert:rules_view',
ruleCreate: 'package_traffic_alert:rule_create',
ruleUpdate: 'package_traffic_alert:rule_update',
ruleEnable: 'package_traffic_alert:rule_enable',
ruleDisable: 'package_traffic_alert:rule_disable',
recordsView: 'package_traffic_alert:records_view',
recordDetail: 'package_traffic_alert:record_detail',
export: 'package_traffic_alert:export'
},
expiringAsset: {
page: 'expiring_asset:page',
export: 'expiring_asset:export'
},
refund: {
page: 'refund:page',
detailPage: 'refund:detail_page',
recoverApproval: 'refund:recover_approval'
},
agentFundOverview: {
page: 'agent_fund_overview:page',
commissionExport: 'agent_fund_overview:commission_export'
},
assetWalletAutoRenewal: {
page: 'asset_wallet_auto_renewal:page',
update: 'asset_wallet_auto_renewal:update'
},
pollingPriorityQueue: {
page: 'polling_priority_queue:page',
create: 'polling_priority_queue:create',
detail: 'polling_priority_queue:detail'
},
operationsReports: {
activationPage: 'operations_reports:activation_page',
activationExport: 'operations_reports:activation_export',
renewalPage: 'operations_reports:renewal_page',
renewalExport: 'operations_reports:renewal_export'
}
} as const

View File

@@ -16,19 +16,25 @@ export const BUSINESS_USER_GROUP_BUSINESS_LINE_OPTIONS: Array<{
]
/** 业务线文案映射 */
export const BUSINESS_USER_GROUP_BUSINESS_LINE_MAP = BUSINESS_USER_GROUP_BUSINESS_LINE_OPTIONS.reduce(
(map, item) => {
map[item.value] = item
return map
},
{} as Record<BusinessUserGroupBusinessLine, (typeof BUSINESS_USER_GROUP_BUSINESS_LINE_OPTIONS)[number]>
)
export const BUSINESS_USER_GROUP_BUSINESS_LINE_MAP =
BUSINESS_USER_GROUP_BUSINESS_LINE_OPTIONS.reduce(
(map, item) => {
map[item.value] = item
return map
},
{} as Record<
BusinessUserGroupBusinessLine,
(typeof BUSINESS_USER_GROUP_BUSINESS_LINE_OPTIONS)[number]
>
)
/** 获取业务线标签 */
export function getBusinessUserGroupBusinessLineLabel(businessLine?: string | null): string {
if (!businessLine) return '-'
return BUSINESS_USER_GROUP_BUSINESS_LINE_MAP[businessLine as BusinessUserGroupBusinessLine]
?.label ?? businessLine
return (
BUSINESS_USER_GROUP_BUSINESS_LINE_MAP[businessLine as BusinessUserGroupBusinessLine]?.label ??
businessLine
)
}
/** 业务用户组页面与按钮权限编码 */
@@ -43,6 +49,7 @@ export const BUSINESS_USER_GROUP_PERMISSIONS = {
/** 店铺业务负责人运营权限编码 */
export const SHOP_BUSINESS_OWNER_PERMISSIONS = {
batch: 'shop:business_owner_batch',
importPage: 'shop:business_owner_import',
importCreate: 'shop:business_owner_import'
}
importPage: 'shop:business_owner_import_view',
importCreate: 'shop:business_owner_import_create',
importDetail: 'shop:business_owner_import_detail'
}

View File

@@ -1,10 +1,13 @@
import type { ExportTaskScene } from '@/types/api'
export interface ExportTaskScenePermissions {
page: string
detail: string
download: string
}
export const EXPORT_TASK_DETAIL_PAGE_PERMISSION = 'export_task:detail_page'
export interface ExportTaskSceneConfig {
scene: ExportTaskScene
sceneName: string
@@ -18,6 +21,7 @@ export const EXPORT_TASK_SCENE_CONFIG: Record<ExportTaskScene, ExportTaskSceneCo
sceneName: '设备管理',
pageTitle: '导出设备',
permissions: {
page: 'export_task:device_page',
detail: 'export_task:device_detail',
download: 'export_task:device_download'
}
@@ -27,6 +31,7 @@ export const EXPORT_TASK_SCENE_CONFIG: Record<ExportTaskScene, ExportTaskSceneCo
sceneName: 'IOT卡管理',
pageTitle: '导出IOT卡',
permissions: {
page: 'export_task:iot_card_page',
detail: 'export_task:iot_card_detail',
download: 'export_task:iot_card_download'
}
@@ -36,6 +41,7 @@ export const EXPORT_TASK_SCENE_CONFIG: Record<ExportTaskScene, ExportTaskSceneCo
sceneName: '订单管理',
pageTitle: '导出订单',
permissions: {
page: 'export_task:order_page',
detail: 'export_task:order_detail',
download: 'export_task:order_download'
}
@@ -45,6 +51,7 @@ export const EXPORT_TASK_SCENE_CONFIG: Record<ExportTaskScene, ExportTaskSceneCo
sceneName: '套餐管理',
pageTitle: '导出套餐',
permissions: {
page: 'export_task:package_page',
detail: 'export_task:package_detail',
download: 'export_task:package_download'
}
@@ -54,6 +61,7 @@ export const EXPORT_TASK_SCENE_CONFIG: Record<ExportTaskScene, ExportTaskSceneCo
sceneName: '代理主钱包流水',
pageTitle: '导出代理主钱包流水',
permissions: {
page: 'export_task:agent_wallet_transaction_page',
detail: 'export_task:agent_wallet_transaction_detail',
download: 'export_task:agent_wallet_transaction_download'
}
@@ -63,6 +71,7 @@ export const EXPORT_TASK_SCENE_CONFIG: Record<ExportTaskScene, ExportTaskSceneCo
sceneName: '代理充值',
pageTitle: '导出代理充值',
permissions: {
page: 'export_task:agent_recharge_page',
detail: 'export_task:agent_recharge_detail',
download: 'export_task:agent_recharge_download'
}
@@ -72,6 +81,7 @@ export const EXPORT_TASK_SCENE_CONFIG: Record<ExportTaskScene, ExportTaskSceneCo
sceneName: '退款',
pageTitle: '导出退款',
permissions: {
page: 'export_task:refund_page',
detail: 'export_task:refund_detail',
download: 'export_task:refund_download'
}
@@ -81,6 +91,7 @@ export const EXPORT_TASK_SCENE_CONFIG: Record<ExportTaskScene, ExportTaskSceneCo
sceneName: '换货',
pageTitle: '导出换货',
permissions: {
page: 'export_task:exchange_page',
detail: 'export_task:exchange_detail',
download: 'export_task:exchange_download'
}
@@ -90,6 +101,7 @@ export const EXPORT_TASK_SCENE_CONFIG: Record<ExportTaskScene, ExportTaskSceneCo
sceneName: '佣金明细',
pageTitle: '导出佣金明细',
permissions: {
page: 'export_task:commission_record_page',
detail: 'export_task:commission_record_detail',
download: 'export_task:commission_record_download'
}
@@ -99,6 +111,7 @@ export const EXPORT_TASK_SCENE_CONFIG: Record<ExportTaskScene, ExportTaskSceneCo
sceneName: '套餐真流量达量预警',
pageTitle: '导出套餐真流量达量预警',
permissions: {
page: 'export_task:package_traffic_alert_page',
detail: 'export_task:package_traffic_alert_detail',
download: 'export_task:package_traffic_alert_download'
}
@@ -108,6 +121,7 @@ export const EXPORT_TASK_SCENE_CONFIG: Record<ExportTaskScene, ExportTaskSceneCo
sceneName: '临期资产',
pageTitle: '导出临期资产',
permissions: {
page: 'export_task:expiring_asset_page',
detail: 'export_task:expiring_asset_detail',
download: 'export_task:expiring_asset_download'
}
@@ -117,6 +131,7 @@ export const EXPORT_TASK_SCENE_CONFIG: Record<ExportTaskScene, ExportTaskSceneCo
sceneName: '设备激活情况报表',
pageTitle: '导出设备激活情况报表',
permissions: {
page: 'export_task:operations_activation_page',
detail: 'export_task:operations_activation_detail',
download: 'export_task:operations_activation_download'
}
@@ -126,6 +141,7 @@ export const EXPORT_TASK_SCENE_CONFIG: Record<ExportTaskScene, ExportTaskSceneCo
sceneName: '套餐续费情况报表',
pageTitle: '导出套餐续费情况报表',
permissions: {
page: 'export_task:operations_renewal_page',
detail: 'export_task:operations_renewal_detail',
download: 'export_task:operations_renewal_download'
}

View File

@@ -31,9 +31,9 @@ export const JULY_PERMISSIONS = {
updateExpiryBase: 'series_grants:update_expiry_base'
},
batchPurchase: {
page: 'bulk_purchase:view',
create: 'bulk_purchase:create',
detail: 'bulk_purchase:detail'
page: 'july_bulk_purchase:view',
create: 'july_bulk_purchase:create',
detail: 'july_bulk_purchase:detail'
}
} as const

View File

@@ -4,6 +4,7 @@
* 编码命名参考代理充值页 agent_recharge:<action> 风格。
*/
export const PAYMENT_MERCHANT_POOL_PERMISSIONS = {
page: 'payment_merchant_pool:page',
merchantCreate: 'payment_merchant_pool:merchant_create',
merchantEdit: 'payment_merchant_pool:merchant_edit',
merchantToggle: 'payment_merchant_pool:merchant_toggle',

View File

@@ -26,20 +26,11 @@
"setting": {
"menuType": {
"title": "Menu Layout",
"list": [
"Vertical",
"Horizontal",
"Mixed",
"Dual"
]
"list": ["Vertical", "Horizontal", "Mixed", "Dual"]
},
"theme": {
"title": "Theme Style",
"list": [
"Light",
"Dark",
"System"
]
"list": ["Light", "Dark", "System"]
},
"menu": {
"title": "Menu Style"
@@ -49,17 +40,11 @@
},
"box": {
"title": "Box Style",
"list": [
"Border",
"Shadow"
]
"list": ["Border", "Shadow"]
},
"container": {
"title": "Container Width",
"list": [
"Full",
"Boxed"
]
"list": ["Full", "Boxed"]
},
"basics": {
"title": "Basic Config",
@@ -97,14 +82,8 @@
"notice": {
"title": "Notice",
"btnRead": "Mark as read",
"bar": [
"Notice",
"Message",
"Todo"
],
"text": [
"No"
],
"bar": ["Notice", "Message", "Todo"],
"text": ["No"],
"viewAll": "View all"
},
"worktab": {
@@ -460,7 +439,9 @@
"title": "Shop Management",
"shopList": "Shop List",
"businessUserGroups": "Business User Groups",
"businessOwnerImport": "Business Owner Import"
"businessOwnerImport": "Business Owner Import",
"agentDistributionRegistrations": "Agent Registration Applications",
"agentDistributionRegistrationDetail": "Agent Registration Application Detail"
},
"assetManagement": {
"title": "Asset Management",

View File

@@ -27,20 +27,11 @@
"setting": {
"menuType": {
"title": "菜单布局",
"list": [
"垂直",
"水平",
"混合",
"双列"
]
"list": ["垂直", "水平", "混合", "双列"]
},
"theme": {
"title": "主题风格",
"list": [
"浅色",
"深色",
"系统"
]
"list": ["浅色", "深色", "系统"]
},
"menu": {
"title": "菜单风格"
@@ -50,17 +41,11 @@
},
"box": {
"title": "盒子样式",
"list": [
"边框",
"阴影"
]
"list": ["边框", "阴影"]
},
"container": {
"title": "容器宽度",
"list": [
"铺满",
"定宽"
]
"list": ["铺满", "定宽"]
},
"basics": {
"title": "基础配置",
@@ -98,14 +83,8 @@
"notice": {
"title": "通知",
"btnRead": "标为已读",
"bar": [
"通知",
"消息",
"代办"
],
"text": [
"暂无"
],
"bar": ["通知", "消息", "代办"],
"text": ["暂无"],
"viewAll": "查看全部"
},
"worktab": {
@@ -131,11 +110,7 @@
"admin": "管理员",
"user": "普通用户"
},
"placeholder": [
"请输入手机号",
"请输入密码",
"请拖动滑块完成验证"
],
"placeholder": ["请输入手机号", "请输入密码", "请拖动滑块完成验证"],
"sliderText": "按住滑块拖动",
"sliderSuccessText": "验证成功",
"rememberPwd": "记住密码",
@@ -178,11 +153,7 @@
"register": {
"title": "创建账号",
"subTitle": "欢迎加入我们,请填写以下信息完成注册",
"placeholder": [
"请输入账号",
"请输入密码",
"请再次输入密码"
],
"placeholder": ["请输入账号", "请输入密码", "请再次输入密码"],
"rule": [
"请再次输入密码",
"两次输入密码不一致!",
@@ -396,7 +367,9 @@
"title": "店铺管理",
"shopList": "店铺列表",
"businessUserGroups": "业务用户组",
"businessOwnerImport": "业务负责人导入"
"businessOwnerImport": "业务负责人导入",
"agentDistributionRegistrations": "代理注册申请",
"agentDistributionRegistrationDetail": "代理注册申请详情"
},
"assetManagement": {
"title": "资产管理",

View File

@@ -5,6 +5,10 @@ import { JULY_PERMISSIONS } from '@/config/constants/julyIteration'
import { AUDIT_PERMISSIONS } from '@/config/constants/audit'
import { AUGUST_PERMISSIONS } from '@/config/constants/augustIteration'
import { PAYMENT_MERCHANT_POOL_PERMISSIONS } from '@/config/constants/paymentMerchantPools'
import {
EXPORT_TASK_DETAIL_PAGE_PERMISSION,
EXPORT_TASK_SCENE_CONFIG
} from '@/config/constants/exportTask'
import {
BUSINESS_USER_GROUP_PERMISSIONS,
SHOP_BUSINESS_OWNER_PERMISSIONS
@@ -219,7 +223,8 @@ export const asyncRoutes: AppRouteRecord[] = [
component: RoutesAlias.TrafficAlertRules,
meta: {
title: 'menus.packageManagement.trafficAlertRules',
keepAlive: true
keepAlive: true,
permissions: [AUGUST_PERMISSIONS.packageTrafficAlert.rulesView]
}
},
// 真流量达量预警记录
@@ -229,7 +234,8 @@ export const asyncRoutes: AppRouteRecord[] = [
component: RoutesAlias.TrafficAlerts,
meta: {
title: 'menus.packageManagement.trafficAlerts',
keepAlive: true
keepAlive: true,
permissions: [AUGUST_PERMISSIONS.packageTrafficAlert.recordsView]
}
},
// 真流量达量预警记录详情
@@ -240,7 +246,8 @@ export const asyncRoutes: AppRouteRecord[] = [
meta: {
title: 'menus.packageManagement.trafficAlertDetail',
isHide: true,
keepAlive: false
keepAlive: false,
permissions: [AUGUST_PERMISSIONS.packageTrafficAlert.recordDetail]
}
}
]
@@ -263,7 +270,8 @@ export const asyncRoutes: AppRouteRecord[] = [
component: RoutesAlias.Shop,
meta: {
title: 'menus.shopManagement.shopList',
keepAlive: true
keepAlive: true,
permissions: [AUGUST_PERMISSIONS.shop.listView]
}
},
// 店铺详情
@@ -274,7 +282,8 @@ export const asyncRoutes: AppRouteRecord[] = [
meta: {
title: '店铺详情',
isHide: true,
keepAlive: false
keepAlive: false,
permissions: [AUGUST_PERMISSIONS.shop.detailView]
}
},
// 业务用户组
@@ -300,6 +309,29 @@ export const asyncRoutes: AppRouteRecord[] = [
roles: ['R_SUPER', 'R_ADMIN'],
permissions: [SHOP_BUSINESS_OWNER_PERMISSIONS.importPage]
}
},
// 代理注册申请
{
path: 'agent-distribution-registrations',
name: 'AgentDistributionRegistrations',
component: RoutesAlias.AgentDistributionRegistrations,
meta: {
title: 'menus.shopManagement.agentDistributionRegistrations',
keepAlive: true,
permissions: [AUGUST_PERMISSIONS.agentDistributionRegistration.list]
}
},
// 代理注册申请详情
{
path: 'agent-distribution-registrations/detail/:id',
name: 'AgentDistributionRegistrationDetail',
component: RoutesAlias.AgentDistributionRegistrationDetail,
meta: {
title: 'menus.shopManagement.agentDistributionRegistrationDetail',
isHide: true,
keepAlive: false,
permissions: [AUGUST_PERMISSIONS.agentDistributionRegistration.detail]
}
}
]
},
@@ -375,7 +407,8 @@ export const asyncRoutes: AppRouteRecord[] = [
component: RoutesAlias.ExpiringAssets,
meta: {
title: '临期资产',
keepAlive: true
keepAlive: true,
permissions: [AUGUST_PERMISSIONS.expiringAsset.page]
}
},
// IoT卡管理
@@ -691,7 +724,8 @@ export const asyncRoutes: AppRouteRecord[] = [
meta: {
title: 'menus.assetManagement.exportCommissionRecord',
exportTaskScene: 'commission_record',
keepAlive: true
keepAlive: true,
permissions: [EXPORT_TASK_SCENE_CONFIG.commission_record.permissions.page]
}
},
{
@@ -701,7 +735,8 @@ export const asyncRoutes: AppRouteRecord[] = [
meta: {
title: 'menus.assetManagement.exportPackageTrafficAlert',
exportTaskScene: 'package_traffic_alert',
keepAlive: true
keepAlive: true,
permissions: [EXPORT_TASK_SCENE_CONFIG.package_traffic_alert.permissions.page]
}
},
{
@@ -711,7 +746,8 @@ export const asyncRoutes: AppRouteRecord[] = [
meta: {
title: 'menus.assetManagement.exportExpiringAsset',
exportTaskScene: 'expiring_asset',
keepAlive: true
keepAlive: true,
permissions: [EXPORT_TASK_SCENE_CONFIG.expiring_asset.permissions.page]
}
},
{
@@ -721,7 +757,8 @@ export const asyncRoutes: AppRouteRecord[] = [
meta: {
title: 'menus.assetManagement.exportOperationsActivation',
exportTaskScene: 'operations_activation',
keepAlive: true
keepAlive: true,
permissions: [EXPORT_TASK_SCENE_CONFIG.operations_activation.permissions.page]
}
},
{
@@ -731,7 +768,8 @@ export const asyncRoutes: AppRouteRecord[] = [
meta: {
title: 'menus.assetManagement.exportOperationsRenewal',
exportTaskScene: 'operations_renewal',
keepAlive: true
keepAlive: true,
permissions: [EXPORT_TASK_SCENE_CONFIG.operations_renewal.permissions.page]
}
},
{
@@ -741,7 +779,8 @@ export const asyncRoutes: AppRouteRecord[] = [
meta: {
title: 'menus.assetManagement.exportTaskDetail',
isHide: true,
keepAlive: false
keepAlive: false,
permissions: [EXPORT_TASK_DETAIL_PAGE_PERMISSION]
}
}
]
@@ -821,7 +860,8 @@ export const asyncRoutes: AppRouteRecord[] = [
component: RoutesAlias.RefundManagement,
meta: {
title: 'menus.financialManagement.refundManagement',
keepAlive: true
keepAlive: true,
permissions: [AUGUST_PERMISSIONS.refund.page]
}
},
// 退款详情
@@ -832,7 +872,8 @@ export const asyncRoutes: AppRouteRecord[] = [
meta: {
title: 'menus.financialManagement.refundDetail',
isHide: true,
keepAlive: false
keepAlive: false,
permissions: [AUGUST_PERMISSIONS.refund.detailPage]
}
},
// 员工代收款账单
@@ -901,7 +942,8 @@ export const asyncRoutes: AppRouteRecord[] = [
meta: {
title: 'menus.financialManagement.agentFundOverview',
keepAlive: true,
roles: ['R_SUPER', 'R_ADMIN']
roles: ['R_SUPER', 'R_ADMIN'],
permissions: [AUGUST_PERMISSIONS.agentFundOverview.page]
}
}
]
@@ -1047,7 +1089,8 @@ export const asyncRoutes: AppRouteRecord[] = [
meta: {
title: 'menus.settings.paymentMerchantPools',
keepAlive: true,
allowedUserTypes: [1, 2]
allowedUserTypes: [1, 2],
permissions: [PAYMENT_MERCHANT_POOL_PERMISSIONS.page]
}
},
// 支付商户详情
@@ -1174,7 +1217,7 @@ export const asyncRoutes: AppRouteRecord[] = [
isHide: true,
keepAlive: false,
allowedUserTypes: [1, 2],
permissions: [AUGUST_PERMISSIONS.h5PopupConfiguration.list]
permissions: [AUGUST_PERMISSIONS.h5PopupConfiguration.detail]
}
},
// 资产钱包自动续费配置
@@ -1185,7 +1228,8 @@ export const asyncRoutes: AppRouteRecord[] = [
meta: {
title: 'menus.settings.assetWalletAutoRenewal',
keepAlive: true,
allowedUserTypes: [1, 2]
allowedUserTypes: [1, 2],
permissions: [AUGUST_PERMISSIONS.assetWalletAutoRenewal.page]
}
}
]
@@ -1278,7 +1322,8 @@ export const asyncRoutes: AppRouteRecord[] = [
component: RoutesAlias.PollingPriorityQueue,
meta: {
title: '优先队列',
keepAlive: true
keepAlive: true,
permissions: [AUGUST_PERMISSIONS.pollingPriorityQueue.page]
}
}
]
@@ -1301,7 +1346,8 @@ export const asyncRoutes: AppRouteRecord[] = [
meta: {
title: '设备激活报表',
keepAlive: true,
allowedUserTypes: [1, 2]
allowedUserTypes: [1, 2],
permissions: [AUGUST_PERMISSIONS.operationsReports.activationPage]
}
},
{
@@ -1311,7 +1357,8 @@ export const asyncRoutes: AppRouteRecord[] = [
meta: {
title: '套餐续费报表',
keepAlive: true,
allowedUserTypes: [1, 2]
allowedUserTypes: [1, 2],
permissions: [AUGUST_PERMISSIONS.operationsReports.renewalPage]
}
}
]

View File

@@ -47,6 +47,8 @@ export enum RoutesAlias {
ShopDetail = '/shop-management/detail', // 店铺详情
BusinessUserGroups = '/shop-management/business-user-groups', // 业务用户组
BusinessOwnerImport = '/shop-management/business-owner-import', // 业务负责人导入
AgentDistributionRegistrations = '/shop-management/agent-distribution-registrations', // 代理注册申请
AgentDistributionRegistrationDetail = '/shop-management/agent-distribution-registrations/detail', // 代理注册申请详情
// 通用页面(店铺账号-企业账号)
EnterpriseCustomerAccounts = '/common/account-list', // 企业客户账号列表和店铺账号列表共用

View File

@@ -0,0 +1,56 @@
/** 后台代理注册申请管理类型 */
export interface AgentDistributionRegistrationQueryParams {
page?: number
page_size?: number
status?: 0 | 1 | 2
start_time?: string
end_time?: string
decided_start_time?: string
decided_end_time?: string
phone?: string
keyword?: string
parent_shop_id?: number
submission_anomaly?: boolean
}
export interface AgentDistributionRegistrationItem {
id: number
status: number
status_name?: string | null
approval_status?: number | null
approval_status_name?: string | null
submission_status?: number | null
submission_status_name?: string | null
recoverable?: boolean
failure_summary?: string | null
last_recovery_at?: string | null
approval_instance_id?: number | null
phone: string
username: string
shop_name: string
shop_code: string
contact_name?: string | null
province?: string | null
city?: string | null
district?: string | null
address?: string | null
distribution_code?: string | null
parent_shop_id?: number | null
parent_shop_name?: string | null
reject_reason?: string | null
created_at: string
decided_at?: string | null
}
export interface AgentDistributionRegistrationPageResult {
items: AgentDistributionRegistrationItem[]
page: number
size: number
total: number
}
export interface RecoverAgentDistributionRegistrationResponse {
id: number
message?: string
}

View File

@@ -75,6 +75,7 @@ export * from './asset'
// 代理充值相关
export * from './agentRecharge'
export * from './agentDistributionRegistration'
// 支付设置相关
export * from './paymentSettings'

View File

@@ -27,7 +27,9 @@
<ElButton v-if="canDownload" type="success" link @click="downloadExport">
下载
</ElButton>
<ElButton type="primary" :loading="exporting" @click="handleExport">导出</ElButton>
<ElButton v-if="canExport" type="primary" :loading="exporting" @click="handleExport">
导出
</ElButton>
</template>
</ArtTableHeader>
@@ -72,11 +74,15 @@
import { useAsyncTaskPolling } from '@/composables/useAsyncTaskPolling'
import { useCheckedColumns } from '@/composables/useCheckedColumns'
import { formatDateTime } from '@/utils/business/format'
import { useAuth } from '@/composables/useAuth'
import { AUGUST_PERMISSIONS } from '@/config/constants/augustIteration'
defineOptions({ name: 'ExpiringAssets' })
const router = useRouter()
const route = useRoute()
const { hasAuth } = useAuth()
const canExport = computed(() => hasAuth(AUGUST_PERMISSIONS.expiringAsset.export))
const tableRef = ref()
const loading = ref(false)
const exporting = ref(false)

View File

@@ -55,8 +55,8 @@
<!-- 佣金明细 Tab -->
<ElTabPane label="佣金明细" name="commission">
<div class="commission-export-actions">
<ElButton
v-if="hasAuth('commission_record:export')"
<ElButton
v-if="hasAuth(AUGUST_PERMISSIONS.agentFundOverview.commissionExport)"
@click="commissionExportDialogVisible = true"
>
导出
@@ -511,6 +511,7 @@
import ExportTaskCreateDialog from '@/components/business/ExportTaskCreateDialog.vue'
import CommissionRecordDetailDialog from '@/components/business/CommissionRecordDetailDialog.vue'
import { AUDIT_PERMISSIONS } from '@/config/constants/audit'
import { AUGUST_PERMISSIONS } from '@/config/constants/augustIteration'
import { resolveFinanceAuditTarget } from '@/utils/business/auditNavigation'
import { openAuditInvestigation } from '@/components/business/audit/investigationController'

View File

@@ -18,7 +18,11 @@
重新申请
</ElButton>
<ElButton
v-if="refund && canRecoverApproval(refund) && hasAuth('refund:detail')"
v-if="
refund &&
canRecoverApproval(refund) &&
hasAuth(AUGUST_PERMISSIONS.refund.recoverApproval)
"
type="warning"
:loading="recoverApprovalLoading"
@click="handleRecoverApproval"
@@ -182,7 +186,7 @@
import { ref, onMounted, computed, h, reactive } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ElButton, ElCard, ElIcon, ElMessage, ElMessageBox } from 'element-plus'
import type { FormInstance, FormRules } from 'element-plus'
import type { FormRules } from 'element-plus'
import { ArrowLeft, Loading } from '@element-plus/icons-vue'
import DetailPage from '@/components/common/DetailPage.vue'
import type { DetailSection } from '@/components/common/DetailPage.vue'
@@ -206,6 +210,7 @@
import RefundApprovalDialog from '@/components/business/RefundApprovalDialog.vue'
import { useAuth } from '@/composables/useAuth'
import { useUserStore } from '@/store/modules/user'
import { AUGUST_PERMISSIONS } from '@/config/constants/augustIteration'
defineOptions({ name: 'RefundDetail' })

View File

@@ -219,6 +219,7 @@
import { getErrorMessage, toVoucherKeyList } from '@/utils/business'
import { RoutesAlias } from '@/router/routesAlias'
import { AUDIT_PERMISSIONS } from '@/config/constants/audit'
import { AUGUST_PERMISSIONS } from '@/config/constants/augustIteration'
import {
resolveAuditResourceTarget,
resolveFinanceAuditTarget
@@ -1112,7 +1113,7 @@
})
}
if (canRecoverApproval(row) && hasAuth('refund:detail')) {
if (canRecoverApproval(row) && hasAuth(AUGUST_PERMISSIONS.refund.recoverApproval)) {
actions.push({
label: '恢复审批',
handler: () => handleRecoverApproval(row),

View File

@@ -18,7 +18,9 @@
@refresh="handleRefresh"
>
<template #left>
<ElButton type="primary" :loading="exporting" @click="handleExport">导出</ElButton>
<ElButton v-if="canExport" type="primary" :loading="exporting" @click="handleExport">
导出
</ElButton>
<span v-if="snapshotText" class="report-snapshot">{{ snapshotText }}</span>
<ElTag v-if="exportTask" :type="exportStatusType" class="report-export-tag">
{{ exportTask.status_name || '处理中' }}
@@ -50,6 +52,8 @@
import type { ActivationSummaryData, ActivationSummaryItem } from '@/types/api'
import type { SearchFormItem } from '@/types'
import { ACTIVATION_GROUP_OPTIONS, ACTIVATION_METRIC_COLUMNS, formatMetric } from '../constants'
import { useAuth } from '@/composables/useAuth'
import { AUGUST_PERMISSIONS } from '@/config/constants/augustIteration'
defineOptions({ name: 'OperationsActivationReport' })
@@ -80,6 +84,8 @@
const loading = ref(false)
const exporting = ref(false)
const { hasAuth } = useAuth()
const canExport = computed(() => hasAuth(AUGUST_PERMISSIONS.operationsReports.activationExport))
const summary = ref<ActivationSummaryData | null>(null)
const searchFormItems: SearchFormItem[] = [

View File

@@ -18,7 +18,9 @@
@refresh="handleRefresh"
>
<template #left>
<ElButton type="primary" :loading="exporting" @click="handleExport">导出</ElButton>
<ElButton v-if="canExport" type="primary" :loading="exporting" @click="handleExport">
导出
</ElButton>
<span v-if="snapshotText" class="report-snapshot">{{ snapshotText }}</span>
<ElTag v-if="exportTask" :type="exportStatusType" class="report-export-tag">
{{ exportTask.status_name || '处理中' }}
@@ -50,6 +52,8 @@
import type { RenewalSummaryData, RenewalSummaryItem } from '@/types/api'
import type { SearchFormItem } from '@/types'
import { RENEWAL_GROUP_OPTIONS, RENEWAL_METRIC_COLUMNS, formatMetric } from '../constants'
import { useAuth } from '@/composables/useAuth'
import { AUGUST_PERMISSIONS } from '@/config/constants/augustIteration'
defineOptions({ name: 'OperationsRenewalReport' })
@@ -80,6 +84,8 @@
const loading = ref(false)
const exporting = ref(false)
const { hasAuth } = useAuth()
const canExport = computed(() => hasAuth(AUGUST_PERMISSIONS.operationsReports.renewalExport))
const summary = ref<RenewalSummaryData | null>(null)
const searchFormItems: SearchFormItem[] = [

View File

@@ -127,7 +127,6 @@
import { useAuth } from '@/composables/useAuth'
import { useCheckedColumns } from '@/composables/useCheckedColumns'
import { formatDateTime } from '@/utils/business/format'
import { normalizeApiError } from '@/utils/business/apiError'
import { AUGUST_PERMISSIONS } from '@/config/constants'
import type { SearchFormItem } from '@/types'
import type {
@@ -143,6 +142,8 @@
const canCreate = computed(() => hasAuth(perms.ruleCreate))
const canUpdate = computed(() => hasAuth(perms.ruleUpdate))
const canEnable = computed(() => hasAuth(perms.ruleEnable))
const canDisable = computed(() => hasAuth(perms.ruleDisable))
// ========== 列表数据 ==========
@@ -333,15 +334,16 @@
handler: () => void
type?: 'primary' | 'danger'
}> = []
if (!canUpdate.value) return actions
actions.push({ label: '编辑', handler: () => openFormDialog('edit', row) })
if (row.enabled) {
if (canUpdate.value) {
actions.push({ label: '编辑', handler: () => openFormDialog('edit', row) })
}
if (row.enabled && canDisable.value) {
actions.push({
label: '停用',
handler: () => handleToggleEnabled(row, false),
type: 'danger' as const
})
} else {
} else if (!row.enabled && canEnable.value) {
actions.push({
label: '启用',
handler: () => handleToggleEnabled(row, true),

View File

@@ -18,7 +18,9 @@
@refresh="handleRefresh"
>
<template #left>
<el-button type="primary" @click="showCreateDialog">人工优先入队</el-button>
<el-button v-if="canCreate" type="primary" @click="showCreateDialog">
人工优先入队
</el-button>
</template>
</ArtTableHeader>
@@ -187,9 +189,15 @@
POLLING_PRIORITY_TRIGGER_TYPE_OPTIONS,
getPollingPriorityResultName
} from '@/config/constants'
import { AUGUST_PERMISSIONS } from '@/config/constants/augustIteration'
import { useAuth } from '@/composables/useAuth'
defineOptions({ name: 'PollingPriorityQueue' })
const { hasAuth } = useAuth()
const canCreate = computed(() => hasAuth(AUGUST_PERMISSIONS.pollingPriorityQueue.create))
const canDetail = computed(() => hasAuth(AUGUST_PERMISSIONS.pollingPriorityQueue.detail))
const loading = ref(false)
const tableData = ref<PollingPriorityItem[]>([])
const tableRef = ref()
@@ -329,7 +337,8 @@
}))
)
const getActions = () => [{ label: '详情', handler: showDetail, type: 'primary' as const }]
const getActions = () =>
canDetail.value ? [{ label: '详情', handler: showDetail, type: 'primary' as const }] : []
const loadData = async () => {
loading.value = true

View File

@@ -74,7 +74,9 @@
</div>
<div class="form-actions">
<ElButton type="primary" :loading="saving" @click="handleSave">保存配置</ElButton>
<ElButton v-if="canUpdate" type="primary" :loading="saving" @click="handleSave">
保存配置
</ElButton>
<ElButton :disabled="saving" @click="loadConfig">重新加载</ElButton>
</div>
</template>
@@ -84,7 +86,7 @@
</template>
<script setup lang="ts">
import { onMounted, reactive, ref } from 'vue'
import { computed, onMounted, reactive, ref } from 'vue'
import { ElMessage, type FormInstance, type FormRules } from 'element-plus'
import { AssetWalletService, PackageManageService } from '@/api/modules'
import type {
@@ -94,10 +96,14 @@
} from '@/types/api'
import { formatDateTime } from '@/utils/business/format'
import { usePermission } from '@/composables/usePermission'
import { useAuth } from '@/composables/useAuth'
import { AUGUST_PERMISSIONS } from '@/config/constants/augustIteration'
defineOptions({ name: 'AssetWalletAutoRenewal' })
const { isPlatformAccount } = usePermission()
const { hasAuth } = useAuth()
const canUpdate = computed(() => hasAuth(AUGUST_PERMISSIONS.assetWalletAutoRenewal.update))
const formRef = ref<FormInstance>()
const loading = ref(false)

View File

@@ -0,0 +1,154 @@
<template>
<div class="registration-detail-page">
<ElCard shadow="never">
<div class="detail-header">
<ElButton @click="router.back()">返回</ElButton>
<h2>代理注册申请详情</h2>
<ElButton
v-if="
application?.recoverable &&
hasAuth(AUGUST_PERMISSIONS.agentDistributionRegistration.recoverApproval)
"
type="warning"
:loading="recovering"
@click="recoverApproval"
>
恢复审批
</ElButton>
</div>
<ElDescriptions v-if="application" :column="2" border>
<ElDescriptionsItem label="申请ID">{{ application.id }}</ElDescriptionsItem>
<ElDescriptionsItem label="业务状态">{{
application.status_name || '-'
}}</ElDescriptionsItem>
<ElDescriptionsItem label="审批状态">{{
application.approval_status_name || '-'
}}</ElDescriptionsItem>
<ElDescriptionsItem label="企微提交状态">{{
application.submission_status_name || '-'
}}</ElDescriptionsItem>
<ElDescriptionsItem label="手机号">{{ application.phone }}</ElDescriptionsItem>
<ElDescriptionsItem label="用户名">{{ application.username }}</ElDescriptionsItem>
<ElDescriptionsItem label="店铺名称">{{ application.shop_name }}</ElDescriptionsItem>
<ElDescriptionsItem label="店铺编号">{{ application.shop_code }}</ElDescriptionsItem>
<ElDescriptionsItem label="上级店铺">{{
application.parent_shop_name || '-'
}}</ElDescriptionsItem>
<ElDescriptionsItem label="联系人">{{
application.contact_name || '-'
}}</ElDescriptionsItem>
<ElDescriptionsItem label="分销码">{{
application.distribution_code || '-'
}}</ElDescriptionsItem>
<ElDescriptionsItem label="申请时间">{{
formatDateTime(application.created_at)
}}</ElDescriptionsItem>
<ElDescriptionsItem label="省市区" :span="2">
{{
[application.province, application.city, application.district]
.filter(Boolean)
.join(' / ') || '-'
}}
</ElDescriptionsItem>
<ElDescriptionsItem label="详细地址" :span="2">{{
application.address || '-'
}}</ElDescriptionsItem>
<ElDescriptionsItem label="驳回原因" :span="2">{{
application.reject_reason || '-'
}}</ElDescriptionsItem>
<ElDescriptionsItem label="提交失败摘要" :span="2">{{
application.failure_summary || '-'
}}</ElDescriptionsItem>
<ElDescriptionsItem label="最近恢复时间">{{
application.last_recovery_at ? formatDateTime(application.last_recovery_at) : '-'
}}</ElDescriptionsItem>
</ElDescriptions>
<ElEmpty v-else-if="!loading" description="暂无详情" />
<div v-if="loading" class="loading">加载中...</div>
</ElCard>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus'
import { AgentDistributionService } from '@/api/modules'
import { AUGUST_PERMISSIONS } from '@/config/constants/augustIteration'
import { useAuth } from '@/composables/useAuth'
import { formatDateTime } from '@/utils/business/format'
import type { AgentDistributionRegistrationItem } from '@/types/api'
defineOptions({ name: 'AgentDistributionRegistrationDetail' })
const route = useRoute()
const router = useRouter()
const { hasAuth } = useAuth()
const loading = ref(false)
const recovering = ref(false)
const application = ref<AgentDistributionRegistrationItem | null>(null)
const id = Number(route.params.id)
const loadDetail = async () => {
loading.value = true
try {
const res = await AgentDistributionService.getRegistrationApplicationDetail(id)
if (res.code === 0) application.value = res.data
else ElMessage.error(res.msg || '获取代理注册申请详情失败')
} finally {
loading.value = false
}
}
const recoverApproval = async () => {
if (!application.value?.recoverable || recovering.value) return
try {
await ElMessageBox.confirm('确定要恢复该代理注册申请的原审批提交吗?', '恢复审批', {
type: 'warning',
confirmButtonText: '确定',
cancelButtonText: '取消'
})
} catch {
return
}
recovering.value = true
try {
const res = await AgentDistributionService.recoverRegistrationApproval(id)
if (res.code === 0) {
ElMessage.success(res.msg || '恢复审批成功')
await loadDetail()
} else {
ElMessage.error(res.msg || '恢复审批失败')
await loadDetail()
}
} finally {
recovering.value = false
}
}
onMounted(loadDetail)
</script>
<style scoped lang="scss">
.registration-detail-page {
padding: 20px;
}
.detail-header {
display: flex;
align-items: center;
gap: 16px;
margin-bottom: 20px;
}
.detail-header h2 {
flex: 1;
margin: 0;
}
.loading {
padding: 40px;
text-align: center;
}
</style>

View File

@@ -0,0 +1,254 @@
<template>
<ArtTableFullScreen>
<div class="agent-registration-page" id="table-full-screen">
<ArtSearchBar
v-model:filter="searchForm"
:items="searchFormItems"
show-expand
label-width="100px"
@reset="handleReset"
@search="handleSearch"
/>
<ElCard shadow="never" class="art-table-card">
<ArtTableHeader
:columnList="columnOptions"
v-model:columns="columnChecks"
@refresh="handleRefresh"
/>
<ArtTable
:loading="loading"
:data="items"
:currentPage="pagination.page"
:pageSize="pagination.pageSize"
:total="pagination.total"
:marginTop="10"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
>
<template #default>
<ElTableColumn v-for="col in columns" :key="col.prop || col.type" v-bind="col" />
</template>
</ArtTable>
</ElCard>
</div>
</ArtTableFullScreen>
</template>
<script setup lang="ts">
import { h, onMounted, reactive, ref } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage, ElTag } from 'element-plus'
import { AgentDistributionService } from '@/api/modules'
import { AUGUST_PERMISSIONS } from '@/config/constants/augustIteration'
import { useAuth } from '@/composables/useAuth'
import { useCheckedColumns } from '@/composables/useCheckedColumns'
import { RoutesAlias } from '@/router/routesAlias'
import { formatDateTime } from '@/utils/business/format'
import type { SearchFormItem } from '@/types'
import type {
AgentDistributionRegistrationItem,
AgentDistributionRegistrationQueryParams
} from '@/types/api'
defineOptions({ name: 'AgentDistributionRegistrations' })
const router = useRouter()
const { hasAuth } = useAuth()
const loading = ref(false)
const items = ref<AgentDistributionRegistrationItem[]>([])
const pagination = reactive({ page: 1, pageSize: 20, total: 0 })
const searchForm = reactive({
status: undefined as 0 | 1 | 2 | undefined,
phone: '',
keyword: '',
dateRange: [] as string[],
submission_anomaly: undefined as number | undefined
})
const searchFormItems: SearchFormItem[] = [
{
label: '业务状态',
prop: 'status',
type: 'select',
options: [
{ label: '待审批', value: 0 },
{ label: '已通过', value: 1 },
{ label: '已驳回', value: 2 }
],
config: { clearable: true, placeholder: '请选择业务状态' }
},
{
label: '手机号',
prop: 'phone',
type: 'input',
config: { clearable: true, placeholder: '请输入手机号' }
},
{
label: '关键字',
prop: 'keyword',
type: 'input',
config: { clearable: true, placeholder: '店铺/用户名/联系人' }
},
{
label: '申请时间',
prop: 'dateRange',
type: 'datetimerange',
config: {
type: 'datetimerange',
valueFormat: 'YYYY-MM-DDTHH:mm:ssZ',
rangeSeparator: '至',
startPlaceholder: '申请开始',
endPlaceholder: '申请结束'
}
},
{
label: '提交异常',
prop: 'submission_anomaly',
type: 'select',
options: [
{ label: '仅异常', value: 1 },
{ label: '非异常', value: 0 }
],
config: { clearable: true, placeholder: '全部' }
}
]
const columnOptions = [
{ label: '申请店铺', prop: 'shop_name' },
{ label: '用户名', prop: 'username' },
{ label: '手机号', prop: 'phone' },
{ label: '上级店铺', prop: 'parent_shop_name' },
{ label: '业务状态', prop: 'status_name' },
{ label: '审批状态', prop: 'approval_status_name' },
{ label: '企微提交状态', prop: 'submission_status_name' },
{ label: '可恢复', prop: 'recoverable' },
{ label: '申请时间', prop: 'created_at' }
]
const formatStatus = (row: AgentDistributionRegistrationItem) =>
h(
ElTag,
{ type: row.status === 1 ? 'success' : row.status === 2 ? 'danger' : 'warning' },
() => row.status_name || '-'
)
const { columnChecks, columns } = useCheckedColumns(() => [
{
prop: 'shop_name',
label: '申请店铺',
minWidth: 180,
showOverflowTooltip: true,
formatter: (row: AgentDistributionRegistrationItem) =>
h(
'span',
{
style: 'color: var(--el-color-primary); cursor: pointer; text-decoration: underline;',
onClick: () => openDetail(row)
},
row.shop_name
)
},
{ prop: 'username', label: '用户名', width: 140 },
{ prop: 'phone', label: '手机号', width: 140 },
{
prop: 'parent_shop_name',
label: '上级店铺',
width: 150,
formatter: (row: AgentDistributionRegistrationItem) => row.parent_shop_name || '-'
},
{ prop: 'status_name', label: '业务状态', width: 110, formatter: formatStatus },
{
prop: 'approval_status_name',
label: '审批状态',
width: 130,
formatter: (row: AgentDistributionRegistrationItem) => row.approval_status_name || '-'
},
{
prop: 'submission_status_name',
label: '企微提交状态',
width: 140,
formatter: (row: AgentDistributionRegistrationItem) => row.submission_status_name || '-'
},
{
prop: 'recoverable',
label: '可恢复',
width: 90,
formatter: (row: AgentDistributionRegistrationItem) =>
h(ElTag, { type: row.recoverable ? 'warning' : 'info' }, () =>
row.recoverable ? '是' : '否'
)
},
{
prop: 'created_at',
label: '申请时间',
width: 180,
formatter: (row: AgentDistributionRegistrationItem) => formatDateTime(row.created_at)
}
])
const getParams = (): AgentDistributionRegistrationQueryParams => ({
page: pagination.page,
page_size: pagination.pageSize,
status: searchForm.status,
phone: searchForm.phone.trim() || undefined,
keyword: searchForm.keyword.trim() || undefined,
start_time: searchForm.dateRange[0] || undefined,
end_time: searchForm.dateRange[1] || undefined,
submission_anomaly:
searchForm.submission_anomaly === undefined ? undefined : searchForm.submission_anomaly === 1
})
const loadData = async () => {
loading.value = true
try {
const res = await AgentDistributionService.getRegistrationApplications(getParams())
if (res.code === 0 && res.data) {
items.value = res.data.items || []
pagination.total = res.data.total || 0
} else {
ElMessage.error(res.msg || '获取代理注册申请失败')
}
} finally {
loading.value = false
}
}
const handleSearch = () => {
pagination.page = 1
loadData()
}
const handleReset = () => {
searchForm.status = undefined
searchForm.phone = ''
searchForm.keyword = ''
searchForm.dateRange = []
searchForm.submission_anomaly = undefined
handleSearch()
}
const handleRefresh = () => loadData()
const handleSizeChange = (size: number) => {
pagination.pageSize = size
pagination.page = 1
loadData()
}
const handleCurrentChange = (page: number) => {
pagination.page = page
loadData()
}
const openDetail = (row: AgentDistributionRegistrationItem) => {
if (!hasAuth(AUGUST_PERMISSIONS.agentDistributionRegistration.detail)) {
ElMessage.warning('您没有查看代理注册申请详情的权限')
return
}
router.push(`${RoutesAlias.AgentDistributionRegistrationDetail}/${row.id}`)
}
onMounted(loadData)
</script>

View File

@@ -45,6 +45,8 @@
:pageSize="pagination.pageSize"
:total="pagination.total"
:marginTop="10"
:actions="getActions"
:actionsWidth="90"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
>
@@ -199,9 +201,13 @@
import { useCheckedColumns } from '@/composables/useCheckedColumns'
import { formatDateTime } from '@/utils/business/format'
import { SHOP_BUSINESS_OWNER_PERMISSIONS } from '@/config/constants'
import { useAuth } from '@/composables/useAuth'
defineOptions({ name: 'BusinessOwnerImport' })
const { hasAuth } = useAuth()
const canImportDetail = computed(() => hasAuth(SHOP_BUSINESS_OWNER_PERMISSIONS.importDetail))
const importStatusOptions = [
{ label: '待处理', value: 1 },
{ label: '处理中', value: 2 },
@@ -251,6 +257,7 @@
{
style: 'color: var(--el-color-primary); cursor: pointer; text-decoration: underline;',
onClick: (event: MouseEvent) => {
if (!canImportDetail.value) return
event.stopPropagation()
openDetail(row)
}
@@ -349,6 +356,11 @@
getList()
}
const getActions = (row: BusinessOwnerImportDetail) =>
canImportDetail.value
? [{ label: '详情', handler: () => openDetail(row), type: 'primary' as const }]
: []
// ==================== 模板下载 ====================
const handleDownloadTemplate = () => {
try {