fix: Application workflow debug use --bug=1059999 --user=张展玮 【资源管理】继承系统管理员角色的用户,在资源管理中调试应用无权限 https://www.tapd.cn/62980211/s/1749113

This commit is contained in:
zhangzhanwei 2025-08-05 15:57:14 +08:00 committed by zhanweizhang7
parent 1a17c7c5df
commit c48aa77f2f
4 changed files with 59 additions and 72 deletions

View File

@ -1,90 +1,43 @@
<template> <template>
<div <div ref="aiChatRef" class="ai-chat" :class="type" :style="{
ref="aiChatRef" height: firsUserInput ? '100%' : undefined,
class="ai-chat" paddingBottom: applicationDetails.disclaimer ? '20px' : 0,
:class="type" }">
:style="{ <div v-show="showUserInputContent" :class="firsUserInput ? 'firstUserInput' : 'popperUserInput'">
height: firsUserInput ? '100%' : undefined, <UserForm v-model:api_form_data="api_form_data" v-model:form_data="form_data" :application="applicationDetails"
paddingBottom: applicationDetails.disclaimer ? '20px' : 0, :type="type" :first="firsUserInput" @confirm="UserFormConfirm" @cancel="UserFormCancel" ref="userFormRef">
}" </UserForm>
>
<div
v-show="showUserInputContent"
:class="firsUserInput ? 'firstUserInput' : 'popperUserInput'"
>
<UserForm
v-model:api_form_data="api_form_data"
v-model:form_data="form_data"
:application="applicationDetails"
:type="type"
:first="firsUserInput"
@confirm="UserFormConfirm"
@cancel="UserFormCancel"
ref="userFormRef"
></UserForm>
</div> </div>
<template v-if="!(isUserInput || isAPIInput) || !firsUserInput || type === 'log'"> <template v-if="!(isUserInput || isAPIInput) || !firsUserInput || type === 'log'">
<el-scrollbar ref="scrollDiv" @scroll="handleScrollTop"> <el-scrollbar ref="scrollDiv" @scroll="handleScrollTop">
<div ref="dialogScrollbar" class="ai-chat__content p-16"> <div ref="dialogScrollbar" class="ai-chat__content p-16">
<PrologueContent <PrologueContent :type="type" :application="applicationDetails" :available="available"
:type="type" :send-message="sendMessage"></PrologueContent>
:application="applicationDetails"
:available="available"
:send-message="sendMessage"
></PrologueContent>
<template v-for="(item, index) in chatList" :key="index"> <template v-for="(item, index) in chatList" :key="index">
<!-- 问题 --> <!-- 问题 -->
<QuestionContent <QuestionContent :type="type" :application="applicationDetails" :chat-record="item"></QuestionContent>
:type="type"
:application="applicationDetails"
:chat-record="item"
></QuestionContent>
<!-- 回答 --> <!-- 回答 -->
<AnswerContent <AnswerContent :application="applicationDetails" :loading="loading" v-model:chat-record="chatList[index]"
:application="applicationDetails" :type="type" :send-message="sendMessage" :chat-management="ChatManagement"
:loading="loading"
v-model:chat-record="chatList[index]"
:type="type"
:send-message="sendMessage"
:chat-management="ChatManagement"
:executionIsRightPanel="props.executionIsRightPanel" :executionIsRightPanel="props.executionIsRightPanel"
@open-execution-detail="emit('openExecutionDetail', chatList[index])" @open-execution-detail="emit('openExecutionDetail', chatList[index])"
@openParagraph="emit('openParagraph', chatList[index])" @openParagraph="emit('openParagraph', chatList[index])" @openParagraphDocument="
@openParagraphDocument="
(val: any) => emit('openParagraphDocument', chatList[index], val) (val: any) => emit('openParagraphDocument', chatList[index], val)
" "></AnswerContent>
></AnswerContent>
</template> </template>
<TransitionContent <TransitionContent v-if="transcribing" :text="t('chat.transcribing')" :type="type"
v-if="transcribing" :application="applicationDetails">
:text="t('chat.transcribing')" </TransitionContent>
:type="type"
:application="applicationDetails"
></TransitionContent>
</div> </div>
</el-scrollbar> </el-scrollbar>
<ChatInputOperate <ChatInputOperate :app-id="appId" :application-details="applicationDetails" :is-mobile="isMobile" :type="type"
:app-id="appId" :send-message="sendMessage" :open-chat-id="openChatId" :validate="validate" :chat-management="ChatManagement"
:application-details="applicationDetails" v-model:chat-id="chartOpenId" v-model:loading="loading" v-model:show-user-input="showUserInput"
:is-mobile="isMobile" v-if="type !== 'log'">
:type="type"
:send-message="sendMessage"
:open-chat-id="openChatId"
:validate="validate"
:chat-management="ChatManagement"
v-model:chat-id="chartOpenId"
v-model:loading="loading"
v-model:show-user-input="showUserInput"
v-if="type !== 'log'"
>
<template #userInput> <template #userInput>
<el-button <el-button v-if="isUserInput || isAPIInput" class="user-input-button mb-8" @click="toggleUserInput">
v-if="isUserInput || isAPIInput"
class="user-input-button mb-8"
@click="toggleUserInput"
>
<AppIcon iconName="app-edit" :size="16" class="mr-4"></AppIcon> <AppIcon iconName="app-edit" :size="16" class="mr-4"></AppIcon>
<span class="ellipsis"> <span class="ellipsis">
{{ userInputTitle || $t('chat.userInput') }} {{ userInputTitle || $t('chat.userInput') }}
@ -102,6 +55,7 @@ import { type Ref, ref, nextTick, computed, watch, reactive, onMounted, onBefore
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import applicationApi from '@/api/application/application' import applicationApi from '@/api/application/application'
import chatAPI from '@/api/chat/chat' import chatAPI from '@/api/chat/chat'
import SystemResourceManagementApplicationAPI from "@/api/system-resource-management/application.ts"
import chatLogApi from '@/api/application/chat-log' import chatLogApi from '@/api/application/chat-log'
import { ChatManagement, type chatType } from '@/api/type/application' import { ChatManagement, type chatType } from '@/api/type/application'
import { randomId } from '@/utils/common' import { randomId } from '@/utils/common'
@ -329,7 +283,11 @@ const getChatMessageAPI = () => {
} }
const getOpenChatAPI = () => { const getOpenChatAPI = () => {
if (props.type === 'debug-ai-chat') { if (props.type === 'debug-ai-chat') {
return applicationApi.open if (route.path.includes('resource-management')) {
return SystemResourceManagementApplicationAPI.open
} else {
return applicationApi.open
}
} else { } else {
return (a?: string, loading?: Ref<boolean>) => { return (a?: string, loading?: Ref<boolean>) => {
return chatAPI.open(loading) return chatAPI.open(loading)
@ -650,20 +608,24 @@ defineExpose({
</script> </script>
<style lang="scss"> <style lang="scss">
@use './index.scss'; @use './index.scss';
.firstUserInput { .firstUserInput {
height: 100%; height: 100%;
display: flex; display: flex;
justify-content: center; justify-content: center;
overflow: auto; overflow: auto;
.user-form-container { .user-form-container {
max-width: 70%; max-width: 70%;
} }
} }
.debug-ai-chat { .debug-ai-chat {
.user-form-container { .user-form-container {
max-width: 100%; max-width: 100%;
} }
} }
.popperUserInput { .popperUserInput {
position: absolute; position: absolute;
z-index: 999; z-index: 999;
@ -675,10 +637,12 @@ defineExpose({
.video-stop-button { .video-stop-button {
box-shadow: 0px 6px 24px 0px rgba(31, 35, 41, 0.08); box-shadow: 0px 6px 24px 0px rgba(31, 35, 41, 0.08);
&:hover { &:hover {
background: #ffffff; background: #ffffff;
} }
} }
@media only screen and (max-width: 768px) { @media only screen and (max-width: 768px) {
.firstUserInput { .firstUserInput {
.user-form-container { .user-form-container {

View File

@ -29,6 +29,14 @@ const systemManage = {
], ],
'OR' 'OR'
), ),
debug: () =>
hasPermission(
[
RoleConst.ADMIN,
PermissionConst.RESOURCE_APPLICATION_DEBUG
],
'OR'
),
folderDelete: () => false, folderDelete: () => false,
overview_embed: () => overview_embed: () =>
hasPermission( hasPermission(

View File

@ -33,6 +33,16 @@ const workspace = {
], ],
'OR' 'OR'
), ),
debug: (source_id:string) =>
hasPermission(
[
new ComplexPermission([RoleConst.USER],[PermissionConst.APPLICATION.getApplicationWorkspaceResourcePermission(source_id)],[],'AND'),
RoleConst.WORKSPACE_MANAGE.getWorkspaceRole,
PermissionConst.APPLICATION_DEBUG.getWorkspacePermissionWorkspaceManageRole,
PermissionConst.APPLICATION_DEBUG.getApplicationWorkspaceResourcePermission(source_id)
],
'OR'
),
folderEdit: () => folderEdit: () =>
hasPermission( hasPermission(
[ [

View File

@ -30,7 +30,7 @@
<el-button icon="Plus" @click="showPopover = !showPopover"> <el-button icon="Plus" @click="showPopover = !showPopover">
{{ $t('views.applicationWorkflow.setting.addComponent') }} {{ $t('views.applicationWorkflow.setting.addComponent') }}
</el-button> </el-button>
<el-button @click="clickShowDebug" :disabled="showDebug"> <el-button @click="clickShowDebug" :disabled="showDebug" v-if="permissionPrecise.debug(id)">
<AppIcon iconName="app-debug-outlined" class="mr-4"></AppIcon> <AppIcon iconName="app-debug-outlined" class="mr-4"></AppIcon>
{{ $t('views.applicationWorkflow.setting.debug') }} {{ $t('views.applicationWorkflow.setting.debug') }}
</el-button> </el-button>
@ -156,6 +156,7 @@ import { hasPermission } from '@/utils/permission'
import { t } from '@/locales' import { t } from '@/locales'
import { ComplexPermission } from '@/utils/permission/type' import { ComplexPermission } from '@/utils/permission/type'
import { EditionConst, PermissionConst, RoleConst } from '@/utils/permission/data' import { EditionConst, PermissionConst, RoleConst } from '@/utils/permission/data'
import permissionMap from '@/permission'
import { loadSharedApi } from '@/utils/dynamics-api/shared-api' import { loadSharedApi } from '@/utils/dynamics-api/shared-api'
provide('getApplicationDetail', () => detail) provide('getApplicationDetail', () => detail)
const { theme } = useStore() const { theme } = useStore()
@ -172,6 +173,10 @@ const apiType = computed(() => {
} }
}) })
const permissionPrecise = computed(() => {
return permissionMap['application'][apiType.value]
})
const isDefaultTheme = computed(() => { const isDefaultTheme = computed(() => {
return theme.isDefaultTheme() return theme.isDefaultTheme()
}) })