diff --git a/apps/src/api/legacy/app-system.ts b/apps/src/api/legacy/app-system.ts index ca037d6..096a0a9 100644 --- a/apps/src/api/legacy/app-system.ts +++ b/apps/src/api/legacy/app-system.ts @@ -130,6 +130,26 @@ export interface AppHomePopupItem { version?: number; } +export interface AppAgoraErrorLogItem { + agoraUid?: string; + bannedByServer?: boolean; + clientIp?: string; + connectionChangedReasonType?: string; + createTime?: string; + errorCodeType?: string; + id?: string; + isTimeout?: boolean; + networkType?: string; + rawPayload?: string; + reqAppIntel?: string; + reqClient?: string; + roomId?: string; + sysOrigin?: string; + tokenRequestSuccess?: boolean | null; + userAgent?: string; + userId?: string; +} + export async function loginLoggerPage(params: Record) { return requestClient.get('/user/login/logger/page', { params, @@ -250,6 +270,13 @@ export async function deleteAppHomePopup(id: number | string) { return requestClient.delete(`/go/app-system/home-popups/configs/${id}`); } +export async function pageAgoraErrorLogs(params: Record) { + return requestClient.get>( + '/go/app-system/error-logs/agora/page', + { params }, + ); +} + export async function getEnumConfigByGroup(group: string) { return requestClient.get<{ result: LegacyEnumConfigItem[] }>( `/sys/enum/config/list/${group}`, diff --git a/apps/src/router/access.ts b/apps/src/router/access.ts index 105b66c..4f33889 100644 --- a/apps/src/router/access.ts +++ b/apps/src/router/access.ts @@ -68,6 +68,10 @@ const LOCAL_RESIDENT_ACTIVITY_FALLBACK_ROUTES = new Set([ 'ResidentVoiceRoomRocket', ]); +const LOCAL_APP_SYSTEM_FALLBACK_ROUTES = new Set([ + 'AppSystemAgoraErrorLog', +]); + function normalizeRoutePath(path?: string | null) { return String(path || '') .trim() @@ -115,6 +119,7 @@ function buildAuthorizedMenuMatcher(menus: LegacyMenu[]) { const aliasSet = new Set(); const routerSet = new Set(); const titleSet = new Set(); + let hasAppSystemAccess = false; let hasResidentActivityAccess = false; const queue = [...menus]; @@ -142,6 +147,14 @@ function buildAuthorizedMenuMatcher(menus: LegacyMenu[]) { ) { hasResidentActivityAccess = true; } + if ( + String(item.alias || '') === 'AppSystemManager' || + menuName === 'App系统管理' || + normalizedRouter === 'app/sys/mamange' || + normalizedRouter.startsWith('app/sys/mamange/') + ) { + hasAppSystemAccess = true; + } if (Array.isArray(item.childrens) && item.childrens.length > 0) { queue.push(...item.childrens); } @@ -154,6 +167,12 @@ function buildAuthorizedMenuMatcher(menus: LegacyMenu[]) { ) { return true; } + if ( + hasAppSystemAccess && + LOCAL_APP_SYSTEM_FALLBACK_ROUTES.has(String(route.name || '')) + ) { + return true; + } for (const alias of collectRouteAliases(route)) { if (aliasSet.has(alias)) { return true; diff --git a/apps/src/router/routes/modules/app-system.ts b/apps/src/router/routes/modules/app-system.ts index 66315ca..42f75ee 100644 --- a/apps/src/router/routes/modules/app-system.ts +++ b/apps/src/router/routes/modules/app-system.ts @@ -34,6 +34,20 @@ const routes: RouteRecordRaw[] = [ component: () => import('#/views/app-system/request-log.vue'), meta: { title: '请求日志' }, }, + { + name: 'AppSystemErrorLog', + path: 'error-log', + redirect: '/app/sys/mamange/error-log/agora', + meta: { title: '错误日志' }, + children: [ + { + name: 'AppSystemAgoraErrorLog', + path: 'agora', + component: () => import('#/views/app-system/agora-error-log.vue'), + meta: { title: '声网' }, + }, + ], + }, { name: 'AppSystemSpecialId', path: 'userSpecialId', diff --git a/apps/src/views/app-system/agora-error-log.vue b/apps/src/views/app-system/agora-error-log.vue new file mode 100644 index 0000000..9bdd1fa --- /dev/null +++ b/apps/src/views/app-system/agora-error-log.vue @@ -0,0 +1,346 @@ + + + + + diff --git a/apps/src/views/props/components/resource-config-modal.vue b/apps/src/views/props/components/resource-config-modal.vue index 8860b8c..2bcae4d 100644 --- a/apps/src/views/props/components/resource-config-modal.vue +++ b/apps/src/views/props/components/resource-config-modal.vue @@ -2,8 +2,20 @@ import { computed, reactive, ref, watch } from 'vue'; import { - OSS_FILE_BUCKETS, + Button, + Form, + FormItem, + Image, + Input, + message, + Modal, + Select, + Switch, +} from 'antdv-next'; + +import { getAccessImgUrl, + OSS_FILE_BUCKETS, simpleUploadFile, } from '#/api/legacy/oss'; import { @@ -11,21 +23,9 @@ import { updatePropsSource, } from '#/api/legacy/props'; -import { - Button, - Form, - FormItem, - Image, - Input, - Modal, - Select, - Switch, - message, -} from 'antdv-next'; - import { NOBLE_VIP_OPTIONS, - PROPS_TYPES, + PROPS_RESOURCE_CONFIG_TYPES, } from '../shared'; const props = defineProps<{ @@ -63,17 +63,26 @@ const form = reactive>({ const isUpdate = computed(() => Boolean(form.id)); const isImageSourceType = computed(() => - ['THEME', 'LAYOUT', 'CHAT_BUBBLE'].includes(form.type), + ['CHAT_BUBBLE', 'LAYOUT', 'THEME'].includes(form.type), ); const isAmountRequired = computed( () => !['CUSTOMIZE', 'FRAGMENTS'].includes(form.type), ); -const isSourceRequired = computed( +const showSourceUpload = computed( () => !['CUSTOMIZE', 'FRAGMENTS'].includes(form.type), ); +const isSourceRequired = computed( + () => !['BADGE', 'CUSTOMIZE', 'FRAGMENTS'].includes(form.type), +); const showExpandUpload = computed(() => form.type === 'CHAT_BUBBLE'); +const sourceUploadLabel = computed(() => { + if (showExpandUpload.value) { + return 'iOS资源'; + } + return isSourceRequired.value ? '资源' : '资源(选填)'; +}); const title = computed(() => (isUpdate.value ? '修改资源' : '新增资源')); -const propsTypeOptions = PROPS_TYPES.map((item) => ({ +const propsTypeOptions = PROPS_RESOURCE_CONFIG_TYPES.map((item) => ({ label: item.name, value: item.value as any, })); @@ -92,7 +101,7 @@ function resetForm() { form.name = ''; form.sourceUrl = ''; form.sysOrigin = props.sysOriginOptions[0]?.value ?? 'LIKEI'; - form.type = PROPS_TYPES[0]?.value ?? ''; + form.type = PROPS_RESOURCE_CONFIG_TYPES[0]?.value ?? ''; } watch( @@ -235,11 +244,7 @@ async function handleSubmit() { ...form, amount: isAmountRequired.value ? Number(form.amount) : 0, }; - if (isUpdate.value) { - await updatePropsSource(payload); - } else { - await addPropsSource(payload); - } + await (isUpdate.value ? updatePropsSource(payload) : addPropsSource(payload)); message.success('保存成功'); emit('success'); emit('close'); @@ -261,9 +266,10 @@ async function handleSubmit() { >
- + /> >({}); const query = reactive({ date: '', dateType: 'MONTH', - propsType: PROPS_TYPES[0]?.value ?? 'AVATAR_FRAME', + propsType: PROPS_RESOURCE_CONFIG_TYPES[0]?.value ?? 'AVATAR_FRAME', sysOrigin: '', }); @@ -66,7 +66,7 @@ const dateTypeOptions = ACTIVITY_DATE_TYPE_OPTIONS.map((item) => ({ label: item.label, value: item.value as any, })); -const propsTypeOptions = PROPS_TYPES.map((item) => ({ +const propsTypeOptions = PROPS_RESOURCE_CONFIG_TYPES.map((item) => ({ label: item.name, value: item.value as any, })); @@ -97,7 +97,7 @@ watch( } query.sysOrigin = sysOriginOptions.value[0]?.value || 'LIKEI'; query.dateType = 'MONTH'; - query.propsType = PROPS_TYPES[0]?.value ?? 'AVATAR_FRAME'; + query.propsType = PROPS_RESOURCE_CONFIG_TYPES[0]?.value ?? 'AVATAR_FRAME'; query.date = ACTIVITY_DATE_TYPE_MAP.MONTH.defaultDate; void loadData(); }, @@ -123,9 +123,12 @@ watch( @cancel="emit('close')" > - + @change="loadData" + /> -