feat: optimize admin operate modules
This commit is contained in:
parent
2ef56428dc
commit
1462c296af
@ -13,6 +13,7 @@ import { useAccessStore } from '@vben/stores';
|
|||||||
|
|
||||||
import { message } from 'antdv-next';
|
import { message } from 'antdv-next';
|
||||||
|
|
||||||
|
import { getDevApiBaseURL } from '#/config/dev-api-switch';
|
||||||
import { useAuthStore } from '#/store';
|
import { useAuthStore } from '#/store';
|
||||||
|
|
||||||
const { apiURL } = useAppConfig(import.meta.env, import.meta.env.PROD);
|
const { apiURL } = useAppConfig(import.meta.env, import.meta.env.PROD);
|
||||||
@ -48,6 +49,10 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
|
|||||||
// 请求头处理
|
// 请求头处理
|
||||||
client.addRequestInterceptor({
|
client.addRequestInterceptor({
|
||||||
fulfilled: async (config) => {
|
fulfilled: async (config) => {
|
||||||
|
const devBaseURL = getDevApiBaseURL(String(config.url ?? ''));
|
||||||
|
if (devBaseURL) {
|
||||||
|
config.baseURL = devBaseURL;
|
||||||
|
}
|
||||||
const accessStore = useAccessStore();
|
const accessStore = useAccessStore();
|
||||||
const accessToken = accessStore.accessToken;
|
const accessToken = accessStore.accessToken;
|
||||||
if (accessToken) {
|
if (accessToken) {
|
||||||
|
|||||||
66
apps/src/components/dev-api-switch.vue
Normal file
66
apps/src/components/dev-api-switch.vue
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
|
||||||
|
import { Select, message } from 'antdv-next';
|
||||||
|
|
||||||
|
import {
|
||||||
|
DEV_API_OPTIONS,
|
||||||
|
getDevApiTargetLabel,
|
||||||
|
getStoredDevApiTarget,
|
||||||
|
isDevApiSwitchEnabled,
|
||||||
|
normalizeDevApiTarget,
|
||||||
|
type DevApiTarget,
|
||||||
|
setStoredDevApiTarget,
|
||||||
|
} from '#/config/dev-api-switch';
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: 'DevApiSwitch',
|
||||||
|
});
|
||||||
|
|
||||||
|
const enabled = isDevApiSwitchEnabled();
|
||||||
|
const currentTarget = ref<DevApiTarget>(getStoredDevApiTarget());
|
||||||
|
|
||||||
|
function handleChange(value: string) {
|
||||||
|
const nextTarget = normalizeDevApiTarget(value);
|
||||||
|
if (nextTarget === currentTarget.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
currentTarget.value = nextTarget;
|
||||||
|
setStoredDevApiTarget(nextTarget);
|
||||||
|
message.success(`已切换到${getDevApiTargetLabel(nextTarget)},后续请求将使用对应环境`);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div v-if="enabled" class="dev-api-switch">
|
||||||
|
<span class="dev-api-switch__label">API</span>
|
||||||
|
<Select
|
||||||
|
:value="currentTarget"
|
||||||
|
:options="DEV_API_OPTIONS"
|
||||||
|
class="dev-api-switch__select"
|
||||||
|
option-label-prop="label"
|
||||||
|
size="small"
|
||||||
|
@change="handleChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.dev-api-switch {
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dev-api-switch__label {
|
||||||
|
color: var(--vben-layout-header-text-color, rgb(15 23 42 / 0.72));
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: 0.08em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dev-api-switch__select {
|
||||||
|
width: 128px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
79
apps/src/config/dev-api-switch.ts
Normal file
79
apps/src/config/dev-api-switch.ts
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
export const DEV_API_SWITCH_STORAGE_KEY = '__chatapp3_admin_dev_api_target__';
|
||||||
|
|
||||||
|
export const DEV_API_TARGETS = {
|
||||||
|
internal: 'internal',
|
||||||
|
prod: 'prod',
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export type DevApiTarget =
|
||||||
|
(typeof DEV_API_TARGETS)[keyof typeof DEV_API_TARGETS];
|
||||||
|
|
||||||
|
export const DEV_API_OPTIONS: Array<{
|
||||||
|
label: string;
|
||||||
|
value: DevApiTarget;
|
||||||
|
}> = [
|
||||||
|
{
|
||||||
|
label: '内网 API',
|
||||||
|
value: DEV_API_TARGETS.internal,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '线上 API',
|
||||||
|
value: DEV_API_TARGETS.prod,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const DEV_API_PREFIX_MAP: Record<DevApiTarget, string> = {
|
||||||
|
[DEV_API_TARGETS.internal]: '/__dev_api_internal__',
|
||||||
|
[DEV_API_TARGETS.prod]: '/__dev_api_prod__',
|
||||||
|
};
|
||||||
|
|
||||||
|
function canUseStorage() {
|
||||||
|
return typeof window !== 'undefined' && typeof window.localStorage !== 'undefined';
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isDevApiSwitchEnabled() {
|
||||||
|
return import.meta.env.DEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function normalizeDevApiTarget(value: null | string | undefined): DevApiTarget {
|
||||||
|
return value === DEV_API_TARGETS.prod
|
||||||
|
? DEV_API_TARGETS.prod
|
||||||
|
: DEV_API_TARGETS.internal;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getStoredDevApiTarget(): DevApiTarget {
|
||||||
|
if (!isDevApiSwitchEnabled() || !canUseStorage()) {
|
||||||
|
return DEV_API_TARGETS.internal;
|
||||||
|
}
|
||||||
|
return normalizeDevApiTarget(
|
||||||
|
window.localStorage.getItem(DEV_API_SWITCH_STORAGE_KEY),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setStoredDevApiTarget(target: DevApiTarget) {
|
||||||
|
if (!isDevApiSwitchEnabled() || !canUseStorage()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window.localStorage.setItem(
|
||||||
|
DEV_API_SWITCH_STORAGE_KEY,
|
||||||
|
normalizeDevApiTarget(target),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getDevApiTargetLabel(target: DevApiTarget) {
|
||||||
|
return (
|
||||||
|
DEV_API_OPTIONS.find((item) => item.value === target)?.label ||
|
||||||
|
'内网 API'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getDevApiBaseURL(url?: string) {
|
||||||
|
if (!isDevApiSwitchEnabled()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const normalizedUrl = String(url || '');
|
||||||
|
if (/^https?:\/\//.test(normalizedUrl)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return DEV_API_PREFIX_MAP[getStoredDevApiTarget()];
|
||||||
|
}
|
||||||
@ -17,8 +17,10 @@ import { useAccessStore, useUserStore } from '@vben/stores';
|
|||||||
|
|
||||||
import { $t } from '#/locales';
|
import { $t } from '#/locales';
|
||||||
import { useAuthStore } from '#/store';
|
import { useAuthStore } from '#/store';
|
||||||
|
import DevApiSwitch from '#/components/dev-api-switch.vue';
|
||||||
import LoginForm from '#/views/_core/authentication/login.vue';
|
import LoginForm from '#/views/_core/authentication/login.vue';
|
||||||
|
|
||||||
|
const isDev = import.meta.env.DEV;
|
||||||
const notifications = ref<NotificationItem[]>([
|
const notifications = ref<NotificationItem[]>([
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
@ -141,6 +143,9 @@ watch(
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<BasicLayout @clear-preferences-and-logout="handleLogout">
|
<BasicLayout @clear-preferences-and-logout="handleLogout">
|
||||||
|
<template v-if="isDev" #header-right-55>
|
||||||
|
<DevApiSwitch />
|
||||||
|
</template>
|
||||||
<template #user-dropdown>
|
<template #user-dropdown>
|
||||||
<UserDropdown
|
<UserDropdown
|
||||||
:avatar
|
:avatar
|
||||||
|
|||||||
@ -53,72 +53,18 @@ const routes: RouteRecordRaw[] = [
|
|||||||
component: () => import('#/views/operate/ludo-game.vue'),
|
component: () => import('#/views/operate/ludo-game.vue'),
|
||||||
meta: { title: 'Ludo飞行棋' },
|
meta: { title: 'Ludo飞行棋' },
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: 'SetTop',
|
|
||||||
path: 'set-top-room',
|
|
||||||
component: () => import('#/views/operate/set-top-room.vue'),
|
|
||||||
meta: { title: '置顶房间' },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'SetHot',
|
|
||||||
path: 'set-hot-room',
|
|
||||||
component: () => import('#/views/operate/set-hot-room.vue'),
|
|
||||||
meta: { title: '热门房间' },
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'RefundDeductTagLog',
|
name: 'RefundDeductTagLog',
|
||||||
path: 'refund-deduct-tag-log',
|
path: 'refund-deduct-tag-log',
|
||||||
component: () => import('#/views/operate/refund-deduct-tag-log.vue'),
|
component: () => import('#/views/operate/refund-deduct-tag-log.vue'),
|
||||||
meta: { title: '退款扣除目标' },
|
meta: { title: '退款扣除目标' },
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: 'PayCountry',
|
|
||||||
path: 'pay/country',
|
|
||||||
component: () => import('#/views/operate/pay-country.vue'),
|
|
||||||
meta: { title: '开通支付国家' },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'RegionRelation',
|
|
||||||
path: 'region/relation',
|
|
||||||
component: () => import('#/views/operate/region-relation.vue'),
|
|
||||||
meta: { title: '支付区域关系' },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'PayApplication',
|
|
||||||
path: 'pay/application',
|
|
||||||
component: () => import('#/views/operate/pay-application.vue'),
|
|
||||||
meta: { title: '应用管理' },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'PayFactory',
|
|
||||||
path: 'pay/factory',
|
|
||||||
component: () => import('#/views/operate/pay-factory.vue'),
|
|
||||||
meta: { title: '支付厂商' },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'PayChannel',
|
|
||||||
path: 'pay/channel',
|
|
||||||
component: () => import('#/views/operate/pay-channel.vue'),
|
|
||||||
meta: { title: '支付渠道' },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'OpenPayCountry',
|
|
||||||
path: 'open_pay/country',
|
|
||||||
component: () => import('#/views/operate/pay-country.vue'),
|
|
||||||
meta: { title: '开通支付国家' },
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'OperateCnfLottery',
|
name: 'OperateCnfLottery',
|
||||||
path: 'cnf/lottery',
|
path: 'cnf/lottery',
|
||||||
component: () => import('#/views/operate/lottery-wheel-config.vue'),
|
component: () => import('#/views/operate/lottery-wheel-config.vue'),
|
||||||
meta: { title: '抽奖品配置' },
|
meta: { title: '抽奖品配置' },
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: 'OperateBusinessDevelopment',
|
|
||||||
path: 'room/business-development',
|
|
||||||
component: () => import('#/views/operate/business-development.vue'),
|
|
||||||
meta: { title: 'BD列表' },
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'OperateAdministrator',
|
name: 'OperateAdministrator',
|
||||||
path: 'administrator',
|
path: 'administrator',
|
||||||
@ -215,30 +161,12 @@ const routes: RouteRecordRaw[] = [
|
|||||||
component: () => import('#/views/operate/teen-patti.vue'),
|
component: () => import('#/views/operate/teen-patti.vue'),
|
||||||
meta: { title: '炸金花' },
|
meta: { title: '炸金花' },
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: 'OperateContributionBalance',
|
|
||||||
path: 'contribution/balance',
|
|
||||||
component: () => import('#/views/operate/contribution-balance.vue'),
|
|
||||||
meta: { title: '房间贡献余额' },
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'OperatePush',
|
name: 'OperatePush',
|
||||||
path: 'push',
|
path: 'push',
|
||||||
component: () => import('#/views/operate/push.vue'),
|
component: () => import('#/views/operate/push.vue'),
|
||||||
meta: { title: '消息推送' },
|
meta: { title: '消息推送' },
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: 'OperateOnlineRoom',
|
|
||||||
path: 'online/room',
|
|
||||||
component: () => import('#/views/operate/online-room.vue'),
|
|
||||||
meta: { title: '在线房间' },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'OperateRoomProfile',
|
|
||||||
path: 'profile/room',
|
|
||||||
component: () => import('#/views/operate/room-profile.vue'),
|
|
||||||
meta: { title: '房间资料信息' },
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'OperateSysCountry',
|
name: 'OperateSysCountry',
|
||||||
path: 'sys/country',
|
path: 'sys/country',
|
||||||
@ -293,12 +221,6 @@ const routes: RouteRecordRaw[] = [
|
|||||||
component: () => import('#/views/operate/game-egg.vue'),
|
component: () => import('#/views/operate/game-egg.vue'),
|
||||||
meta: { title: '砸金蛋' },
|
meta: { title: '砸金蛋' },
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: 'ActivityRoomContribution',
|
|
||||||
path: '/activity/room/contribution',
|
|
||||||
component: () => import('#/views/operate/room-contribution.vue'),
|
|
||||||
meta: { title: '房间支持活动' },
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'ActivityHallFame',
|
name: 'ActivityHallFame',
|
||||||
path: '/activity/hall-fame',
|
path: '/activity/hall-fame',
|
||||||
|
|||||||
53
apps/src/router/routes/modules/payment.ts
Normal file
53
apps/src/router/routes/modules/payment.ts
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import type { RouteRecordRaw } from 'vue-router';
|
||||||
|
|
||||||
|
const routes: RouteRecordRaw[] = [
|
||||||
|
{
|
||||||
|
meta: {
|
||||||
|
icon: 'lucide:credit-card',
|
||||||
|
order: 50.1,
|
||||||
|
title: '支付管理',
|
||||||
|
},
|
||||||
|
name: 'PaymentManager',
|
||||||
|
path: '/payment/manager',
|
||||||
|
redirect: '/payment/manager/country',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
name: 'PayCountry',
|
||||||
|
path: 'country',
|
||||||
|
alias: '/operate/manager/pay/country',
|
||||||
|
component: () => import('#/views/operate/pay-country.vue'),
|
||||||
|
meta: { title: '开通支付国家' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'RegionRelation',
|
||||||
|
path: 'region/relation',
|
||||||
|
alias: '/operate/manager/region/relation',
|
||||||
|
component: () => import('#/views/operate/region-relation.vue'),
|
||||||
|
meta: { title: '支付区域关系' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'PayApplication',
|
||||||
|
path: 'application',
|
||||||
|
alias: '/operate/manager/pay/application',
|
||||||
|
component: () => import('#/views/operate/pay-application.vue'),
|
||||||
|
meta: { title: '应用管理' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'PayFactory',
|
||||||
|
path: 'factory',
|
||||||
|
alias: '/operate/manager/pay/factory',
|
||||||
|
component: () => import('#/views/operate/pay-factory.vue'),
|
||||||
|
meta: { title: '支付厂商' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'PayChannel',
|
||||||
|
path: 'channel',
|
||||||
|
alias: '/operate/manager/pay/channel',
|
||||||
|
component: () => import('#/views/operate/pay-channel.vue'),
|
||||||
|
meta: { title: '支付渠道' },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export default routes;
|
||||||
67
apps/src/router/routes/modules/room.ts
Normal file
67
apps/src/router/routes/modules/room.ts
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
import type { RouteRecordRaw } from 'vue-router';
|
||||||
|
|
||||||
|
const routes: RouteRecordRaw[] = [
|
||||||
|
{
|
||||||
|
meta: {
|
||||||
|
icon: 'lucide:house',
|
||||||
|
order: 50.2,
|
||||||
|
title: '房间管理',
|
||||||
|
},
|
||||||
|
name: 'RoomManager',
|
||||||
|
path: '/room/manager',
|
||||||
|
redirect: '/room/manager/set-top-room',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
name: 'SetTop',
|
||||||
|
path: 'set-top-room',
|
||||||
|
alias: '/operate/manager/set-top-room',
|
||||||
|
component: () => import('#/views/operate/set-top-room.vue'),
|
||||||
|
meta: { title: '置顶房间' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'SetHot',
|
||||||
|
path: 'set-hot-room',
|
||||||
|
alias: '/operate/manager/set-hot-room',
|
||||||
|
component: () => import('#/views/operate/set-hot-room.vue'),
|
||||||
|
meta: { title: '热门房间' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'OperateBusinessDevelopment',
|
||||||
|
path: 'business-development',
|
||||||
|
alias: '/operate/manager/room/business-development',
|
||||||
|
component: () => import('#/views/operate/business-development.vue'),
|
||||||
|
meta: { title: 'BD列表' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'OperateContributionBalance',
|
||||||
|
path: 'contribution/balance',
|
||||||
|
alias: '/operate/manager/contribution/balance',
|
||||||
|
component: () => import('#/views/operate/contribution-balance.vue'),
|
||||||
|
meta: { title: '房间贡献余额' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'OperateOnlineRoom',
|
||||||
|
path: 'online/room',
|
||||||
|
alias: '/operate/manager/online/room',
|
||||||
|
component: () => import('#/views/operate/online-room.vue'),
|
||||||
|
meta: { title: '在线房间' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'OperateRoomProfile',
|
||||||
|
path: 'profile/room',
|
||||||
|
alias: '/operate/manager/profile/room',
|
||||||
|
component: () => import('#/views/operate/room-profile.vue'),
|
||||||
|
meta: { title: '房间资料信息' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ActivityRoomContribution',
|
||||||
|
path: 'activity/room/contribution',
|
||||||
|
alias: '/activity/room/contribution',
|
||||||
|
component: () => import('#/views/operate/room-contribution.vue'),
|
||||||
|
meta: { title: '房间支持活动' },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export default routes;
|
||||||
@ -14,11 +14,12 @@ import {
|
|||||||
FormItem,
|
FormItem,
|
||||||
Input,
|
Input,
|
||||||
Select,
|
Select,
|
||||||
SelectOption,
|
|
||||||
Space,
|
Space,
|
||||||
message,
|
message,
|
||||||
} from 'antdv-next';
|
} from 'antdv-next';
|
||||||
|
|
||||||
|
import TeamCountrySelect from '#/views/team/components/team-country-select.vue';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
open: boolean;
|
open: boolean;
|
||||||
userId: number | string;
|
userId: number | string;
|
||||||
@ -31,26 +32,58 @@ const emit = defineEmits<{
|
|||||||
|
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const birthday = ref('');
|
const birthday = ref('');
|
||||||
const form = reactive<Record<string, any>>({
|
|
||||||
bornDay: '',
|
const genderOptions = [
|
||||||
bornMonth: '',
|
{ label: '女', value: 0 },
|
||||||
bornYear: '',
|
{ label: '男', value: 1 },
|
||||||
countryName: '',
|
];
|
||||||
id: '',
|
|
||||||
userNickname: '',
|
function createForm() {
|
||||||
userSex: undefined,
|
return {
|
||||||
});
|
bornDay: '',
|
||||||
|
bornMonth: '',
|
||||||
|
bornYear: '',
|
||||||
|
countryCode: '',
|
||||||
|
countryId: '',
|
||||||
|
countryName: '',
|
||||||
|
id: '',
|
||||||
|
userNickname: '',
|
||||||
|
userSex: undefined as number | undefined,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const form = reactive<Record<string, any>>(createForm());
|
||||||
|
|
||||||
|
function normalizeUserSex(value: number | string | undefined) {
|
||||||
|
if (value === '' || value === null || value === undefined) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
const nextValue = Number(value);
|
||||||
|
return Number.isNaN(nextValue) ? undefined : nextValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleCountryChange(
|
||||||
|
_value: number | string,
|
||||||
|
row: Record<string, any> | null,
|
||||||
|
) {
|
||||||
|
form.countryId = row?.id || '';
|
||||||
|
form.countryCode = row?.alphaTwo || row?.alphaThree || '';
|
||||||
|
form.countryName = row?.aliasName || row?.countryName || '';
|
||||||
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => [props.open, props.userId],
|
() => [props.open, props.userId],
|
||||||
async ([open, userId]) => {
|
async ([open, userId]) => {
|
||||||
if (!open || !userId) {
|
if (!open || !userId) {
|
||||||
|
Object.assign(form, createForm());
|
||||||
|
birthday.value = '';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
try {
|
try {
|
||||||
const data = await getUserBaseInfo(String(userId));
|
const data = await getUserBaseInfo(String(userId));
|
||||||
Object.assign(form, data || {});
|
Object.assign(form, createForm(), data || {});
|
||||||
|
form.userSex = normalizeUserSex(data?.userSex);
|
||||||
birthday.value =
|
birthday.value =
|
||||||
data?.bornYear && data?.bornMonth && data?.bornDay
|
data?.bornYear && data?.bornMonth && data?.bornDay
|
||||||
? `${String(data.bornYear)}-${String(data.bornMonth).padStart(2, '0')}-${String(data.bornDay).padStart(2, '0')}`
|
? `${String(data.bornYear)}-${String(data.bornMonth).padStart(2, '0')}-${String(data.bornDay).padStart(2, '0')}`
|
||||||
@ -120,10 +153,13 @@ async function handleSubmit() {
|
|||||||
<Input v-model:value="form.userNickname" :disabled="loading" />
|
<Input v-model:value="form.userNickname" :disabled="loading" />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
<FormItem label="性别">
|
<FormItem label="性别">
|
||||||
<Select option-label-prop="children" v-model:value="form.userSex" :disabled="loading">
|
<Select
|
||||||
<SelectOption :value="0">女</SelectOption>
|
v-model:value="form.userSex"
|
||||||
<SelectOption :value="1">男</SelectOption>
|
:disabled="loading"
|
||||||
</Select>
|
:options="genderOptions"
|
||||||
|
option-label-prop="label"
|
||||||
|
placeholder="请选择性别"
|
||||||
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
<FormItem label="出生日期">
|
<FormItem label="出生日期">
|
||||||
<DatePicker
|
<DatePicker
|
||||||
@ -134,7 +170,11 @@ async function handleSubmit() {
|
|||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
<FormItem label="国家">
|
<FormItem label="国家">
|
||||||
<Input v-model:value="form.countryName" disabled />
|
<TeamCountrySelect
|
||||||
|
v-model:value="form.countryId"
|
||||||
|
:disabled="loading"
|
||||||
|
@change="handleCountryChange"
|
||||||
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
||||||
|
|||||||
@ -6,14 +6,12 @@ import {
|
|||||||
updateBdLead,
|
updateBdLead,
|
||||||
} from '#/api/legacy/team';
|
} from '#/api/legacy/team';
|
||||||
import AccountInput from '#/components/account-input.vue';
|
import AccountInput from '#/components/account-input.vue';
|
||||||
import { regionConfigTable } from '#/api/legacy/system';
|
import SystemRegionSelect from '#/views/operate/components/system-region-select.vue';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Form,
|
Form,
|
||||||
FormItem,
|
FormItem,
|
||||||
Modal,
|
Modal,
|
||||||
Select,
|
|
||||||
SelectOption,
|
|
||||||
Input,
|
Input,
|
||||||
message,
|
message,
|
||||||
} from 'antdv-next';
|
} from 'antdv-next';
|
||||||
@ -30,8 +28,6 @@ const emit = defineEmits<{
|
|||||||
}>();
|
}>();
|
||||||
|
|
||||||
const saving = ref(false);
|
const saving = ref(false);
|
||||||
const regionLoading = ref(false);
|
|
||||||
const regionOptions = ref<Array<Record<string, any>>>([]);
|
|
||||||
|
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
contact: '',
|
contact: '',
|
||||||
@ -52,28 +48,13 @@ watch(
|
|||||||
}
|
}
|
||||||
form.id = String(props.row?.id || '');
|
form.id = String(props.row?.id || '');
|
||||||
form.userId = String(props.row?.userId || props.row?.userProfile?.id || '');
|
form.userId = String(props.row?.userId || props.row?.userProfile?.id || '');
|
||||||
form.sysOrigin = props.sysOrigin || props.row?.sysOrigin || 'LIKEI';
|
form.sysOrigin = props.row?.sysOrigin || props.sysOrigin || 'LIKEI';
|
||||||
form.contact = props.row?.contact || '';
|
form.contact = props.row?.contact || '';
|
||||||
form.regionId = String(props.row?.regionId || '');
|
form.regionId = String(props.row?.regionId || '');
|
||||||
await loadRegions(form.sysOrigin);
|
|
||||||
},
|
},
|
||||||
{ immediate: true },
|
{ immediate: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
async function loadRegions(sysOrigin: string) {
|
|
||||||
if (!sysOrigin) {
|
|
||||||
regionOptions.value = [];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
regionLoading.value = true;
|
|
||||||
try {
|
|
||||||
const result = await regionConfigTable({ sysOrigin });
|
|
||||||
regionOptions.value = result || [];
|
|
||||||
} finally {
|
|
||||||
regionLoading.value = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function handleSubmit() {
|
async function handleSubmit() {
|
||||||
if (!isUpdate.value && !String(form.userId || '').trim()) {
|
if (!isUpdate.value && !String(form.userId || '').trim()) {
|
||||||
message.warning('请输入BD Leader 用户ID');
|
message.warning('请输入BD Leader 用户ID');
|
||||||
@ -124,20 +105,11 @@ async function handleSubmit() {
|
|||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
<FormItem label="区域">
|
<FormItem label="区域">
|
||||||
<Select option-label-prop="label"
|
<SystemRegionSelect
|
||||||
v-model:value="form.regionId"
|
v-model:value="form.regionId"
|
||||||
:loading="regionLoading"
|
|
||||||
placeholder="请选择区域"
|
placeholder="请选择区域"
|
||||||
>
|
:sys-origin="form.sysOrigin"
|
||||||
<SelectOption
|
/>
|
||||||
v-for="item in regionOptions"
|
|
||||||
:key="item.id"
|
|
||||||
:label="item.regionName"
|
|
||||||
:value="String(item.id)"
|
|
||||||
>
|
|
||||||
{{ item.regionName }}
|
|
||||||
</SelectOption>
|
|
||||||
</Select>
|
|
||||||
</FormItem>
|
</FormItem>
|
||||||
<FormItem label="联系方式">
|
<FormItem label="联系方式">
|
||||||
<Input v-model:value="form.contact" placeholder="联系方式" />
|
<Input v-model:value="form.contact" placeholder="联系方式" />
|
||||||
|
|||||||
@ -1,11 +1,43 @@
|
|||||||
import { defineConfig } from '@vben/vite-config';
|
import { defineConfig } from '@vben/vite-config';
|
||||||
|
|
||||||
|
const DEV_CONSOLE_PREFIX = '/console';
|
||||||
|
const DEV_API_INTERNAL_PREFIX = '/__dev_api_internal__';
|
||||||
|
const DEV_API_PROD_PREFIX = '/__dev_api_prod__';
|
||||||
|
const DEV_INTERNAL_CONSOLE_TARGET = 'http://127.0.0.1:2700';
|
||||||
|
const DEV_INTERNAL_GOLANG_TARGET = 'http://127.0.0.1:2900';
|
||||||
|
const DEV_PROD_TARGET = 'https://yumi-admin.haiyihy.com';
|
||||||
|
|
||||||
|
function createPrefixRegExp(prefix: string) {
|
||||||
|
return new RegExp(`^${prefix.replaceAll('/', '\\/')}`);
|
||||||
|
}
|
||||||
|
|
||||||
export default defineConfig(async () => {
|
export default defineConfig(async () => {
|
||||||
return {
|
return {
|
||||||
application: {},
|
application: {},
|
||||||
vite: {
|
vite: {
|
||||||
server: {
|
server: {
|
||||||
proxy: {
|
proxy: {
|
||||||
|
[`${DEV_API_INTERNAL_PREFIX}/go`]: {
|
||||||
|
changeOrigin: true,
|
||||||
|
rewrite: (path) =>
|
||||||
|
path.replace(createPrefixRegExp(`${DEV_API_INTERNAL_PREFIX}/go`), ''),
|
||||||
|
target: DEV_INTERNAL_GOLANG_TARGET,
|
||||||
|
ws: true,
|
||||||
|
},
|
||||||
|
[DEV_API_INTERNAL_PREFIX]: {
|
||||||
|
changeOrigin: true,
|
||||||
|
rewrite: (path) =>
|
||||||
|
path.replace(createPrefixRegExp(DEV_API_INTERNAL_PREFIX), DEV_CONSOLE_PREFIX),
|
||||||
|
target: DEV_INTERNAL_CONSOLE_TARGET,
|
||||||
|
ws: true,
|
||||||
|
},
|
||||||
|
[DEV_API_PROD_PREFIX]: {
|
||||||
|
changeOrigin: true,
|
||||||
|
rewrite: (path) =>
|
||||||
|
path.replace(createPrefixRegExp(DEV_API_PROD_PREFIX), DEV_CONSOLE_PREFIX),
|
||||||
|
target: DEV_PROD_TARGET,
|
||||||
|
ws: true,
|
||||||
|
},
|
||||||
'/console/go': {
|
'/console/go': {
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
rewrite: (path) => path.replace(/^\/console\/go/, ''),
|
rewrite: (path) => path.replace(/^\/console\/go/, ''),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user