修改
This commit is contained in:
parent
1e2aead70f
commit
a5725f23d4
247
apps/src/router/routes/modules/app-user.ts
Normal file
247
apps/src/router/routes/modules/app-user.ts
Normal file
@ -0,0 +1,247 @@
|
||||
import type { RouteRecordRaw } from 'vue-router';
|
||||
|
||||
const routes: RouteRecordRaw[] = [
|
||||
{
|
||||
meta: {
|
||||
icon: 'lucide:users',
|
||||
order: 49.5,
|
||||
title: 'App用户管理',
|
||||
},
|
||||
name: 'AppUserManager',
|
||||
path: '/app-user/manager',
|
||||
redirect: '/app-user/manager/gold-balance',
|
||||
children: [
|
||||
{
|
||||
name: 'GoldBalance',
|
||||
path: 'gold-balance',
|
||||
alias: '/operate/manager/gold-balance',
|
||||
component: () => import('#/views/operate/gold-balance.vue'),
|
||||
meta: { title: '金币余额' },
|
||||
},
|
||||
{
|
||||
name: 'AutoSalaryPayRecord',
|
||||
path: 'auto-salary-pay-record',
|
||||
alias: '/auto-salary-pay-record',
|
||||
component: () => import('#/views/operate/auto-salary-pay-record.vue'),
|
||||
meta: { title: '自动发放工资凭据' },
|
||||
},
|
||||
{
|
||||
name: 'UserBankWithdrawMoneyApply',
|
||||
path: 'withdraw-money-apply-page',
|
||||
alias: '/withdraw-money-apply-page',
|
||||
component: () =>
|
||||
import('#/views/operate/user-bank-withdraw-money-apply.vue'),
|
||||
meta: { title: '用户银行卡提现现金申请' },
|
||||
},
|
||||
{
|
||||
name: 'UserBankWithdrawDiamondApply',
|
||||
path: 'withdraw-diamond-apply-page',
|
||||
alias: '/withdraw-diamond-apply-page',
|
||||
component: () =>
|
||||
import('#/views/operate/user-bank-withdraw-diamond-apply.vue'),
|
||||
meta: { title: '用户银行卡提现钻石申请' },
|
||||
},
|
||||
{
|
||||
name: 'UserBankWithdrawGoldApply',
|
||||
path: 'user-bank-withdraw-gold-apply',
|
||||
alias: '/user-bank-withdraw-gold-apply',
|
||||
component: () =>
|
||||
import('#/views/operate/user-bank-withdraw-gold-apply.vue'),
|
||||
meta: { title: '用户银行金币兑换申请' },
|
||||
},
|
||||
{
|
||||
name: 'UserBankDiamondWithdrawGoldApply',
|
||||
path: 'user-bank-diamond-withdraw-gold-apply',
|
||||
alias: '/user-bank-diamond-withdraw-gold-apply',
|
||||
component: () =>
|
||||
import('#/views/operate/user-bank-diamond-withdraw-gold-apply.vue'),
|
||||
meta: { title: '用户银行卡钻石兑换金币申请' },
|
||||
},
|
||||
{
|
||||
name: 'UserBankBalance',
|
||||
path: 'user-bank-balance',
|
||||
alias: '/user-bank-balance',
|
||||
component: () => import('#/views/operate/user-bank-balance.vue'),
|
||||
meta: { title: '用户银行账户' },
|
||||
},
|
||||
{
|
||||
name: 'UserBankRunningWater',
|
||||
path: 'user-running-water',
|
||||
alias: '/user-running-water',
|
||||
component: () => import('#/views/operate/user-bank-running-water.vue'),
|
||||
meta: { title: '用户银行流水' },
|
||||
},
|
||||
{
|
||||
name: 'InviteUserLog',
|
||||
path: 'invite-user-log',
|
||||
alias: '/operate/manager/invite-user-log',
|
||||
component: () => import('#/views/operate/invite-user-log.vue'),
|
||||
meta: { title: '邀请用户日志' },
|
||||
},
|
||||
{
|
||||
name: 'SysUserFriendshipCard',
|
||||
path: 'sys/friendship-card',
|
||||
alias: '/sys/friendship-card',
|
||||
component: () => import('#/views/operate/friendship-card.vue'),
|
||||
meta: { title: '用户友谊卡配置' },
|
||||
},
|
||||
{
|
||||
name: 'LotfunInviteUserRule',
|
||||
path: 'sys/invite-user-rule',
|
||||
alias: '/sys/invite-user-rule',
|
||||
component: () => import('#/views/operate/invite-user-rule.vue'),
|
||||
meta: { title: '邀请用户配置' },
|
||||
},
|
||||
{
|
||||
name: 'AswatUserAdvertising',
|
||||
path: 'sys/user-advertising',
|
||||
alias: '/sys/user-advertising',
|
||||
component: () => import('#/views/operate/user-advertising.vue'),
|
||||
meta: { title: '用户观看广告配置' },
|
||||
},
|
||||
{
|
||||
name: 'OperateUserFreight',
|
||||
path: 'user_freight',
|
||||
alias: '/operate/manager/user_freight',
|
||||
component: () => import('#/views/operate/user-freight.vue'),
|
||||
meta: { title: '货运代理' },
|
||||
},
|
||||
{
|
||||
name: 'InviteRewardRecord',
|
||||
path: 'user/invite-reward',
|
||||
alias: '/operate/manager/user/invite-reward',
|
||||
component: () => import('#/views/operate/invite-reward.vue'),
|
||||
meta: { title: '邀请用户奖励记录' },
|
||||
},
|
||||
{
|
||||
name: 'OperateImAccountManager',
|
||||
path: 'im/account/manager',
|
||||
alias: '/operate/manager/im/account/manager',
|
||||
component: () => import('#/views/operate/im-account-manager.vue'),
|
||||
meta: { title: 'IM账号管理' },
|
||||
},
|
||||
{
|
||||
name: 'CheckInLog',
|
||||
path: 'check/in/log',
|
||||
alias: '/operate/manager/check/in/log',
|
||||
component: () => import('#/views/operate/check-in-log.vue'),
|
||||
meta: { title: '用户签到' },
|
||||
},
|
||||
{
|
||||
name: 'OperateUserManage',
|
||||
path: 'user',
|
||||
alias: '/operate/manager/user',
|
||||
component: () => import('#/views/operate/user-manage.vue'),
|
||||
meta: { title: '用户列表' },
|
||||
},
|
||||
{
|
||||
name: 'OperateUserDevice',
|
||||
path: 'user/user-device',
|
||||
alias: '/operate/manager/user/user-device',
|
||||
component: () => import('#/views/operate/user-device-list.vue'),
|
||||
meta: { title: '用户最新设备列表' },
|
||||
},
|
||||
{
|
||||
name: 'OperateUserFreightInfoList',
|
||||
path: 'user_freight_info_list',
|
||||
alias: '/operate/manager/user_freight_info_list',
|
||||
component: () => import('#/views/operate/user-freight-info-list.vue'),
|
||||
meta: { title: '货运代理流水' },
|
||||
},
|
||||
{
|
||||
name: 'OperateQualityUsersList',
|
||||
path: 'quality_users_list',
|
||||
alias: '/operate/manager/quality_users_list',
|
||||
component: () => import('#/views/operate/quality-users-list.vue'),
|
||||
meta: { title: '高产用户列表' },
|
||||
},
|
||||
{
|
||||
name: 'OperateGoldRunningWater',
|
||||
path: 'running/water',
|
||||
alias: '/operate/manager/running/water',
|
||||
component: () => import('#/views/operate/gold-running-water.vue'),
|
||||
meta: { title: '金币收支记录' },
|
||||
},
|
||||
{
|
||||
name: 'OperateInsideOperationGold',
|
||||
path: 'inside-operation-gold',
|
||||
alias: '/operate/manager/inside-operation-gold',
|
||||
component: () => import('#/views/operate/inside-operation-gold.vue'),
|
||||
meta: { title: '内部操作金币' },
|
||||
},
|
||||
{
|
||||
name: 'GameCouponRunningWater',
|
||||
path: 'game/coupon/running/water',
|
||||
alias: '/game/coupon/running/water',
|
||||
component: () => import('#/views/operate/game-coupon-running-water.vue'),
|
||||
meta: { title: '游戏券收支记录' },
|
||||
},
|
||||
{
|
||||
name: 'OperateIntegralStream',
|
||||
path: 'integral/stream',
|
||||
alias: '/operate/manager/integral/stream',
|
||||
component: () => import('#/views/operate/integral-stream.vue'),
|
||||
meta: { title: '积分收支记录' },
|
||||
},
|
||||
{
|
||||
name: 'OperateBadgeConfig',
|
||||
path: 'badge',
|
||||
alias: '/operate/manager/badge',
|
||||
component: () => import('#/views/operate/badge-config.vue'),
|
||||
meta: { title: '徽章配置管理' },
|
||||
},
|
||||
{
|
||||
name: 'OperateGiftHistory',
|
||||
path: 'gift/history',
|
||||
alias: '/operate/manager/gift/history',
|
||||
component: () => import('#/views/operate/gift-history.vue'),
|
||||
meta: { title: '礼物赠送记录' },
|
||||
},
|
||||
{
|
||||
name: 'RunningWaterUserProps',
|
||||
path: 'running/water/user/props',
|
||||
alias: '/running/water/user/props',
|
||||
component: () => import('#/views/operate/user-props-running-water.vue'),
|
||||
meta: { title: '用户道具流水' },
|
||||
},
|
||||
{
|
||||
name: 'UserDiamondBalance',
|
||||
path: 'user/diamond-balance',
|
||||
alias: '/user/diamond-balance',
|
||||
component: () => import('#/views/operate/user-diamond-balance.vue'),
|
||||
meta: { title: '用户钻石余额列表' },
|
||||
},
|
||||
{
|
||||
name: 'UserDiamondRunWater',
|
||||
path: 'user/diamond-run-water',
|
||||
alias: '/user/diamond-run-water',
|
||||
component: () =>
|
||||
import('#/views/operate/user-diamond-running-water.vue'),
|
||||
meta: { title: '用户钻石流水列表' },
|
||||
},
|
||||
{
|
||||
name: 'UserActivityReceive',
|
||||
path: 'user/user-activity-receive',
|
||||
alias: '/user/user-activity-receive',
|
||||
component: () => import('#/views/operate/user-activity-receive.vue'),
|
||||
meta: { title: '用户活动领奖记录' },
|
||||
},
|
||||
{
|
||||
name: 'BeautifulNumberApply',
|
||||
path: 'user/beautiful-number-apply',
|
||||
alias: '/user/beautiful-number-apply',
|
||||
component: () => import('#/views/operate/beautiful-number-apply.vue'),
|
||||
meta: { title: '用户申请靓号记录' },
|
||||
},
|
||||
{
|
||||
name: 'OperateBeautifulNumber',
|
||||
path: 'beautiful-number',
|
||||
alias: '/operate/manager/beautiful-number',
|
||||
component: () => import('#/views/operate/beautiful-number.vue'),
|
||||
meta: { title: '靓号池管理' },
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export default routes;
|
||||
@ -9,7 +9,7 @@ const routes: RouteRecordRaw[] = [
|
||||
},
|
||||
name: 'OperateManager',
|
||||
path: '/operate/manager',
|
||||
redirect: '/operate/manager/gold-balance',
|
||||
redirect: '/operate/manager/agentActivity',
|
||||
children: [
|
||||
{
|
||||
name: 'AgentActivity',
|
||||
@ -17,58 +17,6 @@ const routes: RouteRecordRaw[] = [
|
||||
component: () => import('#/views/operate/agent-activity.vue'),
|
||||
meta: { title: '代理活动' },
|
||||
},
|
||||
{
|
||||
name: 'GoldBalance',
|
||||
path: 'gold-balance',
|
||||
component: () => import('#/views/operate/gold-balance.vue'),
|
||||
meta: { title: '金币余额' },
|
||||
},
|
||||
{
|
||||
name: 'AutoSalaryPayRecord',
|
||||
path: '/auto-salary-pay-record',
|
||||
component: () => import('#/views/operate/auto-salary-pay-record.vue'),
|
||||
meta: { title: '自动发放工资凭据' },
|
||||
},
|
||||
{
|
||||
name: 'UserBankWithdrawMoneyApply',
|
||||
path: '/withdraw-money-apply-page',
|
||||
component: () =>
|
||||
import('#/views/operate/user-bank-withdraw-money-apply.vue'),
|
||||
meta: { title: '用户银行卡提现现金申请' },
|
||||
},
|
||||
{
|
||||
name: 'UserBankWithdrawDiamondApply',
|
||||
path: '/withdraw-diamond-apply-page',
|
||||
component: () =>
|
||||
import('#/views/operate/user-bank-withdraw-diamond-apply.vue'),
|
||||
meta: { title: '用户银行卡提现钻石申请' },
|
||||
},
|
||||
{
|
||||
name: 'UserBankWithdrawGoldApply',
|
||||
path: '/user-bank-withdraw-gold-apply',
|
||||
component: () =>
|
||||
import('#/views/operate/user-bank-withdraw-gold-apply.vue'),
|
||||
meta: { title: '用户银行金币兑换申请' },
|
||||
},
|
||||
{
|
||||
name: 'UserBankDiamondWithdrawGoldApply',
|
||||
path: '/user-bank-diamond-withdraw-gold-apply',
|
||||
component: () =>
|
||||
import('#/views/operate/user-bank-diamond-withdraw-gold-apply.vue'),
|
||||
meta: { title: '用户银行卡钻石兑换金币申请' },
|
||||
},
|
||||
{
|
||||
name: 'UserBankBalance',
|
||||
path: '/user-bank-balance',
|
||||
component: () => import('#/views/operate/user-bank-balance.vue'),
|
||||
meta: { title: '用户银行账户' },
|
||||
},
|
||||
{
|
||||
name: 'UserBankRunningWater',
|
||||
path: '/user-running-water',
|
||||
component: () => import('#/views/operate/user-bank-running-water.vue'),
|
||||
meta: { title: '用户银行流水' },
|
||||
},
|
||||
{
|
||||
name: 'CustomerService',
|
||||
path: '/customer-service',
|
||||
@ -87,12 +35,6 @@ const routes: RouteRecordRaw[] = [
|
||||
component: () => import('#/views/operate/game-pk.vue'),
|
||||
meta: { title: 'PK记录' },
|
||||
},
|
||||
{
|
||||
name: 'InviteUserLog',
|
||||
path: 'invite-user-log',
|
||||
component: () => import('#/views/operate/invite-user-log.vue'),
|
||||
meta: { title: '邀请用户日志' },
|
||||
},
|
||||
{
|
||||
name: 'OperateActivityConfig',
|
||||
path: 'activity/cnf',
|
||||
@ -105,24 +47,6 @@ const routes: RouteRecordRaw[] = [
|
||||
component: () => import('#/views/operate/activity-template.vue'),
|
||||
meta: { title: '活动模版' },
|
||||
},
|
||||
{
|
||||
name: 'SysUserFriendshipCard',
|
||||
path: '/sys/friendship-card',
|
||||
component: () => import('#/views/operate/friendship-card.vue'),
|
||||
meta: { title: '用户友谊卡配置' },
|
||||
},
|
||||
{
|
||||
name: 'LotfunInviteUserRule',
|
||||
path: '/sys/invite-user-rule',
|
||||
component: () => import('#/views/operate/invite-user-rule.vue'),
|
||||
meta: { title: '邀请用户配置' },
|
||||
},
|
||||
{
|
||||
name: 'AswatUserAdvertising',
|
||||
path: '/sys/user-advertising',
|
||||
component: () => import('#/views/operate/user-advertising.vue'),
|
||||
meta: { title: '用户观看广告配置' },
|
||||
},
|
||||
{
|
||||
name: 'GameLudo',
|
||||
path: '/game-ludo',
|
||||
@ -189,54 +113,18 @@ const routes: RouteRecordRaw[] = [
|
||||
component: () => import('#/views/operate/lottery-wheel-config.vue'),
|
||||
meta: { title: '抽奖品配置' },
|
||||
},
|
||||
{
|
||||
name: 'OperateUserFreight',
|
||||
path: 'user_freight',
|
||||
component: () => import('#/views/operate/user-freight.vue'),
|
||||
meta: { title: '货运代理' },
|
||||
},
|
||||
{
|
||||
name: 'OperateBusinessDevelopment',
|
||||
path: 'room/business-development',
|
||||
component: () => import('#/views/operate/business-development.vue'),
|
||||
meta: { title: 'BD列表' },
|
||||
},
|
||||
{
|
||||
name: 'InviteRewardRecord',
|
||||
path: 'user/invite-reward',
|
||||
component: () => import('#/views/operate/invite-reward.vue'),
|
||||
meta: { title: '邀请用户奖励记录' },
|
||||
},
|
||||
{
|
||||
name: 'OperateImAccountManager',
|
||||
path: 'im/account/manager',
|
||||
component: () => import('#/views/operate/im-account-manager.vue'),
|
||||
meta: { title: 'IM账号管理' },
|
||||
},
|
||||
{
|
||||
name: 'CheckInLog',
|
||||
path: 'check/in/log',
|
||||
component: () => import('#/views/operate/check-in-log.vue'),
|
||||
meta: { title: '用户签到' },
|
||||
},
|
||||
{
|
||||
name: 'OperateUserManage',
|
||||
path: 'user',
|
||||
component: () => import('#/views/operate/user-manage.vue'),
|
||||
meta: { title: '用户列表' },
|
||||
},
|
||||
{
|
||||
name: 'OperateAdministrator',
|
||||
path: 'administrator',
|
||||
component: () => import('#/views/operate/app-administrator.vue'),
|
||||
meta: { title: 'APP管理员' },
|
||||
},
|
||||
{
|
||||
name: 'OperateUserDevice',
|
||||
path: 'user/user-device',
|
||||
component: () => import('#/views/operate/user-device-list.vue'),
|
||||
meta: { title: '用户最新设备列表' },
|
||||
},
|
||||
{
|
||||
name: 'OperateCompensate',
|
||||
path: 'compensate',
|
||||
@ -255,42 +143,6 @@ const routes: RouteRecordRaw[] = [
|
||||
component: () => import('#/views/operate/order-abnormal.vue'),
|
||||
meta: { title: '异常订单' },
|
||||
},
|
||||
{
|
||||
name: 'OperateUserFreightInfoList',
|
||||
path: 'user_freight_info_list',
|
||||
component: () => import('#/views/operate/user-freight-info-list.vue'),
|
||||
meta: { title: '货运代理流水' },
|
||||
},
|
||||
{
|
||||
name: 'OperateQualityUsersList',
|
||||
path: 'quality_users_list',
|
||||
component: () => import('#/views/operate/quality-users-list.vue'),
|
||||
meta: { title: '高产用户列表' },
|
||||
},
|
||||
{
|
||||
name: 'OperateGoldRunningWater',
|
||||
path: 'running/water',
|
||||
component: () => import('#/views/operate/gold-running-water.vue'),
|
||||
meta: { title: '金币收支记录' },
|
||||
},
|
||||
{
|
||||
name: 'OperateInsideOperationGold',
|
||||
path: 'inside-operation-gold',
|
||||
component: () => import('#/views/operate/inside-operation-gold.vue'),
|
||||
meta: { title: '内部操作金币' },
|
||||
},
|
||||
{
|
||||
name: 'GameCouponRunningWater',
|
||||
path: '/game/coupon/running/water',
|
||||
component: () => import('#/views/operate/game-coupon-running-water.vue'),
|
||||
meta: { title: '游戏券收支记录' },
|
||||
},
|
||||
{
|
||||
name: 'OperateIntegralStream',
|
||||
path: 'integral/stream',
|
||||
component: () => import('#/views/operate/integral-stream.vue'),
|
||||
meta: { title: '积分收支记录' },
|
||||
},
|
||||
{
|
||||
name: 'OperateOrderDetails',
|
||||
path: 'order/details',
|
||||
@ -315,18 +167,6 @@ const routes: RouteRecordRaw[] = [
|
||||
component: () => import('#/views/operate/game-lottery-config.vue'),
|
||||
meta: { title: '抽奖概率配置' },
|
||||
},
|
||||
{
|
||||
name: 'OperateBadgeConfig',
|
||||
path: 'badge',
|
||||
component: () => import('#/views/operate/badge-config.vue'),
|
||||
meta: { title: '徽章配置管理' },
|
||||
},
|
||||
{
|
||||
name: 'OperateGiftHistory',
|
||||
path: 'gift/history',
|
||||
component: () => import('#/views/operate/gift-history.vue'),
|
||||
meta: { title: '礼物赠送记录' },
|
||||
},
|
||||
{
|
||||
name: 'GameRedPacketRecord',
|
||||
path: '/game/red/packet/record',
|
||||
@ -441,31 +281,6 @@ const routes: RouteRecordRaw[] = [
|
||||
component: () => import('#/views/operate/mike-type-list.vue'),
|
||||
meta: { title: '购买麦位类型流水' },
|
||||
},
|
||||
{
|
||||
name: 'RunningWaterUserProps',
|
||||
path: '/running/water/user/props',
|
||||
component: () => import('#/views/operate/user-props-running-water.vue'),
|
||||
meta: { title: '用户道具流水' },
|
||||
},
|
||||
{
|
||||
name: 'UserDiamondBalance',
|
||||
path: '/user/diamond-balance',
|
||||
component: () => import('#/views/operate/user-diamond-balance.vue'),
|
||||
meta: { title: '用户钻石余额列表' },
|
||||
},
|
||||
{
|
||||
name: 'UserDiamondRunWater',
|
||||
path: '/user/diamond-run-water',
|
||||
component: () =>
|
||||
import('#/views/operate/user-diamond-running-water.vue'),
|
||||
meta: { title: '用户钻石流水列表' },
|
||||
},
|
||||
{
|
||||
name: 'UserActivityReceive',
|
||||
path: '/user/user-activity-receive',
|
||||
component: () => import('#/views/operate/user-activity-receive.vue'),
|
||||
meta: { title: '用户活动领奖记录' },
|
||||
},
|
||||
{
|
||||
name: 'GameTrumpet',
|
||||
path: '/game/trumpet',
|
||||
@ -478,18 +293,6 @@ const routes: RouteRecordRaw[] = [
|
||||
component: () => import('#/views/operate/game-egg.vue'),
|
||||
meta: { title: '砸金蛋' },
|
||||
},
|
||||
{
|
||||
name: 'BeautifulNumberApply',
|
||||
path: '/user/beautiful-number-apply',
|
||||
component: () => import('#/views/operate/beautiful-number-apply.vue'),
|
||||
meta: { title: '用户申请靓号记录' },
|
||||
},
|
||||
{
|
||||
name: 'OperateBeautifulNumber',
|
||||
path: 'beautiful-number',
|
||||
component: () => import('#/views/operate/beautiful-number.vue'),
|
||||
meta: { title: '靓号池管理' },
|
||||
},
|
||||
{
|
||||
name: 'ActivityRoomContribution',
|
||||
path: '/activity/room/contribution',
|
||||
|
||||
@ -4,15 +4,17 @@ import { computed, reactive, ref } from 'vue';
|
||||
import { Page } from '@vben/common-ui';
|
||||
import { useAccessStore } from '@vben/stores';
|
||||
|
||||
import { onlineRoom } from '#/api/legacy/room';
|
||||
import { onlineRoom, updateProfile } from '#/api/legacy/room';
|
||||
import { getAllowedSysOrigins } from '#/views/system/shared';
|
||||
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
Empty,
|
||||
Modal,
|
||||
Space,
|
||||
Tag,
|
||||
message,
|
||||
} from 'antdv-next';
|
||||
|
||||
import AccountHandleModal from '#/views/approval/components/account-handle-modal.vue';
|
||||
@ -35,6 +37,7 @@ const regionSelectRef = ref<InstanceType<typeof SystemRegionSelect> | null>(null
|
||||
const loading = ref(false);
|
||||
const searchLoading = ref(false);
|
||||
const list = ref<Array<Record<string, any>>>([]);
|
||||
const roomStatusSavingId = ref<number | string>('');
|
||||
const membersOpen = ref(false);
|
||||
const accountHandleOpen = ref(false);
|
||||
const roomDetailsOpen = ref(false);
|
||||
@ -102,6 +105,38 @@ function openRoomDetails(record: Record<string, any>) {
|
||||
roomDetailsOpen.value = true;
|
||||
}
|
||||
|
||||
function isRoomClosed(record: Record<string, any>) {
|
||||
return record.profile?.event === 'CLOSE';
|
||||
}
|
||||
|
||||
function handleToggleRoomStatus(record: Record<string, any>) {
|
||||
const roomId = record.profile?.id;
|
||||
const userId = record.profile?.userId;
|
||||
if (!roomId || !userId) {
|
||||
message.warning('房间信息不完整,无法操作');
|
||||
return;
|
||||
}
|
||||
const nextEvent = isRoomClosed(record) ? 'AVAILABLE' : 'CLOSE';
|
||||
Modal.confirm({
|
||||
title: nextEvent === 'CLOSE' ? '是否确认关闭该房间?' : '是否确认恢复该房间?',
|
||||
async onOk() {
|
||||
roomStatusSavingId.value = roomId;
|
||||
try {
|
||||
await updateProfile({
|
||||
event: nextEvent,
|
||||
id: roomId,
|
||||
sysOrigin: record.profile?.sysOrigin || query.sysOrigin,
|
||||
userId,
|
||||
});
|
||||
message.success(nextEvent === 'CLOSE' ? '关闭成功' : '恢复成功');
|
||||
await loadData();
|
||||
} finally {
|
||||
roomStatusSavingId.value = '';
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
loadData();
|
||||
</script>
|
||||
|
||||
@ -166,6 +201,14 @@ loadData();
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<Button size="small" type="link" @click="openMembers(item)">在线成员</Button>
|
||||
<Button
|
||||
size="small"
|
||||
type="link"
|
||||
:loading="roomStatusSavingId === item.profile?.id"
|
||||
@click="handleToggleRoomStatus(item)"
|
||||
>
|
||||
{{ isRoomClosed(item) ? '恢复' : '关闭' }}
|
||||
</Button>
|
||||
<Button size="small" type="link" @click="openAccountHandle(item)">账号处理</Button>
|
||||
<Button size="small" type="link" @click="openRoomDetails(item)">房间详情</Button>
|
||||
</div>
|
||||
|
||||
@ -55,6 +55,8 @@ function createEditForm() {
|
||||
roomCover: '',
|
||||
roomDesc: '',
|
||||
roomName: '',
|
||||
sysOrigin: '',
|
||||
userId: '',
|
||||
};
|
||||
}
|
||||
|
||||
@ -69,6 +71,7 @@ const searchLoading = ref(false);
|
||||
const list = ref<Array<Record<string, any>>>([]);
|
||||
const listNotData = ref(false);
|
||||
const loadMoreLoading = ref(false);
|
||||
const roomStatusSavingId = ref<number | string>('');
|
||||
|
||||
const editOpen = ref(false);
|
||||
const uploadLoading = ref(false);
|
||||
@ -127,7 +130,7 @@ const columns = [
|
||||
{ dataIndex: 'room', key: 'room', title: '封面 / 房间信息', width: 320 },
|
||||
{ dataIndex: 'base', key: 'base', title: '房间信息', width: 180 },
|
||||
{ dataIndex: 'time', key: 'time', title: '时间', width: 220 },
|
||||
{ dataIndex: 'actions', key: 'actions', title: '操作', width: 260 },
|
||||
{ dataIndex: 'actions', key: 'actions', title: '操作', width: 320 },
|
||||
];
|
||||
const roomEventSelectOptions = ROOM_EVENT_OPTIONS.map((item) => ({
|
||||
label: item.name,
|
||||
@ -247,6 +250,8 @@ function openEdit(record: Record<string, any>) {
|
||||
roomCover: record.roomCover || '',
|
||||
roomDesc: record.roomDesc || '',
|
||||
roomName: record.roomName || '',
|
||||
sysOrigin: record.sysOrigin || query.sysOrigin,
|
||||
userId: record.userId || '',
|
||||
});
|
||||
editRow.value = record;
|
||||
editOpen.value = true;
|
||||
@ -300,6 +305,36 @@ async function handleSaveEdit() {
|
||||
}
|
||||
}
|
||||
|
||||
function isRoomClosed(record: Record<string, any>) {
|
||||
return record.event === 'CLOSE';
|
||||
}
|
||||
|
||||
function handleToggleRoomStatus(record: Record<string, any>) {
|
||||
if (!record.id || !record.userId) {
|
||||
message.warning('房间信息不完整,无法操作');
|
||||
return;
|
||||
}
|
||||
const nextEvent = isRoomClosed(record) ? 'AVAILABLE' : 'CLOSE';
|
||||
Modal.confirm({
|
||||
title: nextEvent === 'CLOSE' ? '是否确认关闭该房间?' : '是否确认恢复该房间?',
|
||||
async onOk() {
|
||||
roomStatusSavingId.value = record.id;
|
||||
try {
|
||||
await updateProfile({
|
||||
event: nextEvent,
|
||||
id: record.id,
|
||||
sysOrigin: record.sysOrigin || query.sysOrigin,
|
||||
userId: record.userId,
|
||||
});
|
||||
message.success(nextEvent === 'CLOSE' ? '关闭成功' : '恢复成功');
|
||||
await loadData(true);
|
||||
} finally {
|
||||
roomStatusSavingId.value = '';
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function openApproval(record: Record<string, any>, type: string) {
|
||||
approvalType.value = type;
|
||||
approvalRoomId.value = record.id;
|
||||
@ -494,6 +529,14 @@ async function handleCopy(value: number | string) {
|
||||
<Space wrap>
|
||||
<Button size="small" type="link" @click="handleCopy(record.id)">复制ID</Button>
|
||||
<Button size="small" type="link" @click="openEdit(record)">编辑资料</Button>
|
||||
<Button
|
||||
size="small"
|
||||
type="link"
|
||||
:loading="roomStatusSavingId === record.id"
|
||||
@click="handleToggleRoomStatus(record)"
|
||||
>
|
||||
{{ isRoomClosed(record) ? '恢复' : '关闭' }}
|
||||
</Button>
|
||||
<Button size="small" type="link" @click="openRoomMembers(record.id)">成员列表</Button>
|
||||
<Button size="small" type="link" @click="openVisitors(record.id)">访客记录</Button>
|
||||
<Button size="small" type="link" @click="openOperationLogs(record.id)">操作日志</Button>
|
||||
|
||||
@ -1,10 +1,9 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed, reactive, ref } from 'vue';
|
||||
import { computed, onMounted, reactive, ref, watch } from 'vue';
|
||||
|
||||
import { Page } from '@vben/common-ui';
|
||||
import { useAccessStore } from '@vben/stores';
|
||||
|
||||
import { regionConfigTable } from '#/api/legacy/system';
|
||||
import {
|
||||
deleteTeamPolicy,
|
||||
teamPolicyAdd,
|
||||
@ -15,6 +14,7 @@ import {
|
||||
import { listPayOpenCountry } from '#/api/legacy/pay';
|
||||
import InlineFilterField from '#/views/_shared/inline-filter-field.vue';
|
||||
import InlineFilterToolbar from '#/views/_shared/inline-filter-toolbar.vue';
|
||||
import SystemRegionSelect from '#/views/operate/components/system-region-select.vue';
|
||||
import { formatDate, getAllowedSysOrigins } from '#/views/system/shared';
|
||||
|
||||
import {
|
||||
@ -23,9 +23,9 @@ import {
|
||||
Drawer,
|
||||
Empty,
|
||||
Input,
|
||||
InputNumber,
|
||||
Modal,
|
||||
Select,
|
||||
SelectOption,
|
||||
Space,
|
||||
Table,
|
||||
Tag,
|
||||
@ -57,7 +57,6 @@ const sysOriginOptions = computed(() => {
|
||||
});
|
||||
|
||||
const loading = ref(false);
|
||||
const regionLoading = ref(false);
|
||||
const countryLoading = ref(false);
|
||||
const historyLoading = ref(false);
|
||||
const rewardOpen = ref(false);
|
||||
@ -72,7 +71,6 @@ const currentRewardIndex = ref(-1);
|
||||
const data = ref<Record<string, any>>({});
|
||||
const historyList = ref<LegacyTeamPolicyItem[]>([]);
|
||||
const policies = ref<Array<Record<string, any>>>([]);
|
||||
const regionOptions = ref<Array<Record<string, any>>>([]);
|
||||
const countryList = ref<Array<Record<string, any>>>([]);
|
||||
const currentRewardRow = ref<Record<string, any>>({});
|
||||
|
||||
@ -102,6 +100,15 @@ const columns = computed(() => [
|
||||
{ key: 'actions', title: '操作', width: isEditing.value ? 220 : 120, fixed: 'right' as const },
|
||||
]);
|
||||
|
||||
const countryOptions = computed(() =>
|
||||
countryList.value
|
||||
.map((item) => ({
|
||||
label: getCountryLabel(item),
|
||||
value: item.country?.alphaTwo as string | undefined,
|
||||
}))
|
||||
.filter((item) => item.value),
|
||||
);
|
||||
|
||||
function createFormData() {
|
||||
return {
|
||||
countryCode: '',
|
||||
@ -131,26 +138,14 @@ function syncQueryToForm() {
|
||||
formData.sysOrigin = query.sysOrigin;
|
||||
}
|
||||
|
||||
async function loadRegions(sysOrigin: string) {
|
||||
if (!sysOrigin) {
|
||||
regionOptions.value = [];
|
||||
return;
|
||||
}
|
||||
regionLoading.value = true;
|
||||
try {
|
||||
regionOptions.value = await regionConfigTable({ sysOrigin });
|
||||
} finally {
|
||||
regionLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function loadCountries() {
|
||||
if (!meta.value.showCountryFilter) {
|
||||
countryList.value = [];
|
||||
return;
|
||||
}
|
||||
countryLoading.value = true;
|
||||
try {
|
||||
countryList.value = await listPayOpenCountry();
|
||||
countryList.value = (await listPayOpenCountry()) || [];
|
||||
} finally {
|
||||
countryLoading.value = false;
|
||||
}
|
||||
@ -192,12 +187,8 @@ function handleSearch() {
|
||||
void loadData();
|
||||
}
|
||||
|
||||
async function handleSysOriginChange(value: string) {
|
||||
function handleSysOriginChange(value: string) {
|
||||
query.sysOrigin = value;
|
||||
query.region = '';
|
||||
isEditing.value = false;
|
||||
clearCurrentData();
|
||||
await loadRegions(value);
|
||||
}
|
||||
|
||||
function handleRegionChange() {
|
||||
@ -220,11 +211,13 @@ function handleCountryChange(value?: string) {
|
||||
|
||||
function openCreatePolicy() {
|
||||
resetFormData();
|
||||
policies.value = [];
|
||||
syncQueryToForm();
|
||||
policies.value = [createEmptyTeamPolicyRow()];
|
||||
addRowsNumber.value = '1';
|
||||
currentAddRowIndex.value = -1;
|
||||
addRowOpen.value = true;
|
||||
isClickNewPolicyButton.value = true;
|
||||
addRowOpen.value = false;
|
||||
isClickNewPolicyButton.value = false;
|
||||
isEditing.value = true;
|
||||
}
|
||||
|
||||
function openAddRow(index: number) {
|
||||
@ -251,6 +244,20 @@ function handleAddRows() {
|
||||
addRowOpen.value = false;
|
||||
}
|
||||
|
||||
function normalizePolicyItem(item: Record<string, any>) {
|
||||
return {
|
||||
...item,
|
||||
effectiveDay: Number(item.effectiveDay || 0),
|
||||
level: Number(item.level || 0),
|
||||
memberSalary: Number(item.memberSalary || 0),
|
||||
onlineTime: Number(item.onlineTime || 0),
|
||||
ownSalary: Number(item.ownSalary || 0),
|
||||
propsRewards: Array.isArray(item.propsRewards) ? item.propsRewards : [],
|
||||
target: Number(item.target || 0),
|
||||
totalSalary: Number(getTeamPolicyTotalSalary(item)),
|
||||
};
|
||||
}
|
||||
|
||||
function movePolicyUp(index: number) {
|
||||
if (index <= 0) {
|
||||
return;
|
||||
@ -299,6 +306,7 @@ function handleRewardSuccess(rewards: Array<Record<string, any>>) {
|
||||
|
||||
function handleEditHistory(item: LegacyTeamPolicyItem) {
|
||||
policies.value = clonePolicies(item.policy);
|
||||
formData.countryCode = item.countryCode ? String(item.countryCode) : query.countryCode;
|
||||
formData.id = item.id ? String(item.id) : '';
|
||||
formData.region = item.region ? String(item.region) : '';
|
||||
formData.title = item.title || '';
|
||||
@ -329,10 +337,7 @@ async function handleDeleteHistory(id?: number | string) {
|
||||
|
||||
async function persistPolicy(release: boolean) {
|
||||
formData.countryCode = query.countryCode;
|
||||
formData.policy = clonePolicies(policies.value).map((item) => ({
|
||||
...item,
|
||||
totalSalary: getTeamPolicyTotalSalary(item),
|
||||
}));
|
||||
formData.policy = clonePolicies(policies.value).map(normalizePolicyItem);
|
||||
formData.region = query.region;
|
||||
formData.release = release;
|
||||
formData.sysOrigin = query.sysOrigin;
|
||||
@ -345,6 +350,10 @@ async function persistPolicy(release: boolean) {
|
||||
message.warning('请输入政策标题');
|
||||
return;
|
||||
}
|
||||
if (formData.policy.length === 0) {
|
||||
message.warning('请至少添加一条政策');
|
||||
return;
|
||||
}
|
||||
|
||||
loading.value = true;
|
||||
try {
|
||||
@ -380,8 +389,38 @@ function getCountryLabel(item: Record<string, any>) {
|
||||
return item?.country?.aliasName || item?.country?.enName || '-';
|
||||
}
|
||||
|
||||
loadRegions(query.sysOrigin);
|
||||
loadCountries();
|
||||
watch(
|
||||
sysOriginOptions,
|
||||
(options) => {
|
||||
if (!query.sysOrigin) {
|
||||
query.sysOrigin = String(options[0]?.value || '');
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
watch(
|
||||
() => query.sysOrigin,
|
||||
(value, previousValue) => {
|
||||
if (!value) {
|
||||
query.region = '';
|
||||
query.countryCode = '';
|
||||
clearCurrentData();
|
||||
return;
|
||||
}
|
||||
if (value !== previousValue) {
|
||||
query.region = '';
|
||||
query.countryCode = '';
|
||||
isEditing.value = false;
|
||||
clearCurrentData();
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
void loadCountries();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@ -398,23 +437,14 @@ loadCountries();
|
||||
></SysOriginSelect>
|
||||
</InlineFilterField>
|
||||
<InlineFilterField label="区域">
|
||||
<Select option-label-prop="label"
|
||||
<SystemRegionSelect
|
||||
v-model:value="query.region"
|
||||
:loading="regionLoading"
|
||||
allow-clear
|
||||
clearable
|
||||
placeholder="请选择区域"
|
||||
:sys-origin="query.sysOrigin"
|
||||
style="width: 180px"
|
||||
@change="handleRegionChange"
|
||||
>
|
||||
<SelectOption
|
||||
v-for="item in regionOptions"
|
||||
:key="item.id"
|
||||
:label="item.regionName"
|
||||
:value="item.id"
|
||||
>
|
||||
{{ item.regionName }}
|
||||
</SelectOption>
|
||||
</Select>
|
||||
/>
|
||||
</InlineFilterField>
|
||||
<InlineFilterField
|
||||
v-if="meta.showCountryFilter"
|
||||
@ -427,16 +457,8 @@ loadCountries();
|
||||
placeholder="国家"
|
||||
style="width: 220px"
|
||||
@change="handleCountryChange"
|
||||
>
|
||||
<SelectOption
|
||||
v-for="item in countryList"
|
||||
:key="item.id"
|
||||
:label="getCountryLabel(item)"
|
||||
:value="item.country?.alphaTwo"
|
||||
>
|
||||
{{ getCountryLabel(item) }}
|
||||
</SelectOption>
|
||||
</Select>
|
||||
:options="countryOptions"
|
||||
/>
|
||||
</InlineFilterField>
|
||||
<Space wrap>
|
||||
<Button
|
||||
@ -569,39 +591,53 @@ loadCountries();
|
||||
>
|
||||
<template #bodyCell="{ column, index, record }">
|
||||
<template v-if="column.key === 'level'">
|
||||
<Input
|
||||
<InputNumber
|
||||
v-model:value="record.level"
|
||||
:min="0"
|
||||
placeholder="等级"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'onlineTime'">
|
||||
<Input
|
||||
<InputNumber
|
||||
v-model:value="record.onlineTime"
|
||||
:min="0"
|
||||
placeholder="时间"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'effectiveDay'">
|
||||
<Input
|
||||
<InputNumber
|
||||
v-model:value="record.effectiveDay"
|
||||
:min="0"
|
||||
placeholder="有效天"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'target'">
|
||||
<Input
|
||||
<InputNumber
|
||||
v-model:value="record.target"
|
||||
:min="0"
|
||||
placeholder="目标"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'memberSalary'">
|
||||
<Input
|
||||
<InputNumber
|
||||
v-model:value="record.memberSalary"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
:placeholder="meta.memberSalaryLabel"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'ownSalary'">
|
||||
<Input
|
||||
<InputNumber
|
||||
v-model:value="record.ownSalary"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
:placeholder="meta.ownSalaryLabel"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'totalSalary'">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user