fix(系统管理): 用例权限创建修复&列表权限补充&脚本ws协议连接提交测试

This commit is contained in:
xinxin.wu 2024-01-31 12:28:51 +08:00 committed by 刘瑞斌
parent 54d45031fc
commit bb9013de65
11 changed files with 115 additions and 68 deletions

View File

@ -12,6 +12,12 @@ export default mergeConfig(
strict: true, strict: true,
}, },
proxy: { proxy: {
'/ws': {
target: 'http://172.16.200.18:8081/',
changeOrigin: true,
rewrite: (path: string) => path.replace(/^\/front\/ws/, ''),
ws: true,
},
'/front': { '/front': {
target: 'http://172.16.200.18:8081/', target: 'http://172.16.200.18:8081/',
changeOrigin: true, changeOrigin: true,

View File

@ -87,6 +87,7 @@
import { getCommonScriptDetail, getSocket, testCommonScript } from '@/api/modules/project-management/commonScript'; import { getCommonScriptDetail, getSocket, testCommonScript } from '@/api/modules/project-management/commonScript';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import useAppStore from '@/store/modules/app'; import useAppStore from '@/store/modules/app';
import { getGenerateId, sleep } from '@/utils';
import type { AddOrUpdateCommonScript, ParamsRequestType } from '@/models/projectManagement/commonScript'; import type { AddOrUpdateCommonScript, ParamsRequestType } from '@/models/projectManagement/commonScript';
@ -231,22 +232,9 @@
const loading = ref<boolean>(false); const loading = ref<boolean>(false);
const websocket = ref<any>(); const websocket = ref<any>();
const reportId = ref('');
function onDebugMessage(e: any) { async function run() {
if (e.data && e.data.startsWith('result_')) {
try { try {
const data = e.data.substring(7);
websocket.value.close();
console.log(data, 'datadatadatadatadata');
} catch (error) {
websocket.value.close();
}
}
}
//
async function testScript() {
try {
loading.value = true;
const { type, script } = form.value; const { type, script } = form.value;
const parameters = innerParams.value const parameters = innerParams.value
.filter((item: any) => item.name && item.value) .filter((item: any) => item.name && item.value)
@ -262,35 +250,69 @@
script, script,
params: parameters, params: parameters,
projectId: appStore.currentProjectId, projectId: appStore.currentProjectId,
reportId: reportId.value,
}; };
await testCommonScript(params);
const reportId = await testCommonScript(params);
if (reportId) {
websocket.value = getSocket(reportId);
// TODO
// websocket.value.addEventListener('open', (event) => {
// console.log('WebSocket:', event);
// websocket.value.send('Hello, WebSocket Server!');
// });
// websocket.value.addEventListener('message', (event) => {
// console.log(':', event.data);
// });
// websocket.value.addEventListener('close', (event) => {
// console.log('WebSocket:', event);
// });
// websocket.value.addEventListener('error', (event) => {
// console.error('WebSocket:', event);
// });
}
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} finally {
loading.value = false;
} }
} }
//
function onOpen() {
run();
}
const executionResult = ref<string>('');
// TODO
function onDebugMessage(e: any) {
// console.log(e.data);
if (e.data) {
try {
// websocket.value.close();
executionResult.value = JSON.parse(e.data);
console.log(JSON.parse(e.data));
} catch (error) {
// websocket.value.close();
console.log(error);
}
}
}
// TODO
function debugSocket() {
websocket.value = getSocket(reportId.value);
websocket.value.onmessage = onDebugMessage;
websocket.value.onopen = onOpen;
websocket.value.addEventListener('open', (event) => {
console.log('打开:', event);
});
websocket.value.addEventListener('message', (event) => {
console.log('接收:', event.data);
});
websocket.value.addEventListener('close', (event) => {
console.log('关闭:', event);
});
websocket.value.addEventListener('error', (event) => {
console.error('错误:', event);
});
}
//
async function testScript() {
reportId.value = getGenerateId();
}
watch(
() => reportId.value,
(val) => {
if (val) {
debugSocket();
}
}
);
</script> </script>
<style scoped></style> <style scoped></style>

View File

@ -94,6 +94,7 @@
language: Languages; language: Languages;
code: string; code: string;
enableRadioSelected?: boolean; enableRadioSelected?: boolean;
executionResult?: string; //
}>(); }>();
const emit = defineEmits<{ const emit = defineEmits<{
(e: 'update:language', value: Languages): void; (e: 'update:language', value: Languages): void;
@ -101,13 +102,13 @@
}>(); }>();
const { t } = useI18n(); const { t } = useI18n();
const executionResultValue = ref('');
const projectId = ref<string>(appStore.currentProjectId); const projectId = ref<string>(appStore.currentProjectId);
const commonScriptValue = ref(''); const commonScriptValue = ref('');
const innerLanguagesType = useVModel(props, 'language', emit); const innerLanguagesType = useVModel(props, 'language', emit);
const executionResultValue = useVModel(props, 'executionResult', emit);
watch( watch(
() => innerLanguagesType.value, () => innerLanguagesType.value,

View File

@ -34,7 +34,7 @@ const CaseManagement: AppRouteRecordRaw = {
component: () => import('@/views/case-management/caseManagementFeature/components/caseDetail.vue'), component: () => import('@/views/case-management/caseManagementFeature/components/caseDetail.vue'),
meta: { meta: {
locale: 'menu.caseManagement.featureCaseDetail', locale: 'menu.caseManagement.featureCaseDetail',
roles: ['FUNCTIONAL_CASE:READ+EDIT'], roles: ['FUNCTIONAL_CASE:READ+ADD'],
breadcrumbs: [ breadcrumbs: [
{ {
name: CaseManagementRouteEnum.CASE_MANAGEMENT_CASE, name: CaseManagementRouteEnum.CASE_MANAGEMENT_CASE,
@ -56,7 +56,7 @@ const CaseManagement: AppRouteRecordRaw = {
component: () => import('@/views/case-management/caseManagementFeature/components/createSuccess.vue'), component: () => import('@/views/case-management/caseManagementFeature/components/createSuccess.vue'),
meta: { meta: {
locale: 'menu.caseManagement.featureCaseCreateSuccess', locale: 'menu.caseManagement.featureCaseCreateSuccess',
roles: ['FUNCTIONAL_CASE:READ+EDIT'], roles: ['FUNCTIONAL_CASE:READ+ADD'],
}, },
}, },
// 功能用例回收站 // 功能用例回收站
@ -66,7 +66,7 @@ const CaseManagement: AppRouteRecordRaw = {
component: () => import('@/views/case-management/caseManagementFeature/components/recycleCaseTable.vue'), component: () => import('@/views/case-management/caseManagementFeature/components/recycleCaseTable.vue'),
meta: { meta: {
locale: 'menu.caseManagement.featureCaseRecycle', locale: 'menu.caseManagement.featureCaseRecycle',
roles: ['FUNCTIONAL_CASE:READ'], roles: ['FUNCTIONAL_CASE:READ+ADD'],
breadcrumbs: [ breadcrumbs: [
{ {
name: CaseManagementRouteEnum.CASE_MANAGEMENT_CASE, name: CaseManagementRouteEnum.CASE_MANAGEMENT_CASE,

View File

@ -239,6 +239,7 @@
import useFeatureCaseStore from '@/store/modules/case/featureCase'; import useFeatureCaseStore from '@/store/modules/case/featureCase';
import useUserStore from '@/store/modules/user'; import useUserStore from '@/store/modules/user';
import { characterLimit } from '@/utils'; import { characterLimit } from '@/utils';
import { hasAnyPermission } from '@/utils/permission';
import type { CustomAttributes, DetailCase, TabItemType } from '@/models/caseManagement/featureCase'; import type { CustomAttributes, DetailCase, TabItemType } from '@/models/caseManagement/featureCase';
import { ModuleTreeNode } from '@/models/projectManagement/file'; import { ModuleTreeNode } from '@/models/projectManagement/file';
@ -256,7 +257,6 @@
const userStore = useUserStore(); const userStore = useUserStore();
const { t } = useI18n(); const { t } = useI18n();
const { openModal } = useModal(); const { openModal } = useModal();
const props = defineProps<{ const props = defineProps<{
visible: boolean; visible: boolean;
detailId: string; // id detailId: string; // id
@ -461,7 +461,7 @@
options: item.options || [], options: item.options || [],
props: { props: {
modelValue: currentDefaultValue, modelValue: currentDefaultValue,
disabled: isDisabled.value, disabled: !hasAnyPermission(['FUNCTIONAL_CASE:READ+UPDATE']),
options: item.options || [], options: item.options || [],
}, },
}; };

View File

@ -32,7 +32,6 @@
v-on="propsEvent" v-on="propsEvent"
@batch-action="handleTableBatch" @batch-action="handleTableBatch"
@change="changeHandler" @change="changeHandler"
@cell-click="showCaseDetailEvent"
> >
<template #num="{ record, rowIndex }"> <template #num="{ record, rowIndex }">
<span class="flex w-full" @click="showCaseDetail(record.id, rowIndex)">{{ record.num }}</span> <span class="flex w-full" @click="showCaseDetail(record.id, rowIndex)">{{ record.num }}</span>
@ -239,6 +238,7 @@
import { useAppStore, useTableStore } from '@/store'; import { useAppStore, useTableStore } from '@/store';
import useFeatureCaseStore from '@/store/modules/case/featureCase'; import useFeatureCaseStore from '@/store/modules/case/featureCase';
import { characterLimit, findNodeByKey, findNodePathByKey } from '@/utils'; import { characterLimit, findNodeByKey, findNodePathByKey } from '@/utils';
import { hasAnyPermission } from '@/utils/permission';
import type { import type {
CaseManagementTable, CaseManagementTable,
@ -369,7 +369,7 @@
showInTable: true, showInTable: true,
showTooltip: true, showTooltip: true,
width: 300, width: 300,
editType: ColumnEditTypeEnum.INPUT, editType: hasAnyPermission(['FUNCTIONAL_CASE:READ+UPDATE']) ? ColumnEditTypeEnum.INPUT : undefined,
sortable: { sortable: {
sortDirections: ['ascend', 'descend'], sortDirections: ['ascend', 'descend'],
sorter: true, sorter: true,

View File

@ -146,22 +146,26 @@ export function getTableFields(customFields: CustomAttributes[], itemDataIndex:
// 处理多选项 // 处理多选项
if (multipleExcludes.includes(currentColumnData.type)) { if (multipleExcludes.includes(currentColumnData.type)) {
const selectValue = JSON.parse(currentColumnData.defaultValue); const selectValue = JSON.parse(currentColumnData.defaultValue);
return currentColumnData.options return (
(currentColumnData.options || [])
.filter((item: any) => selectValue.includes(item.value)) .filter((item: any) => selectValue.includes(item.value))
.map((it: any) => it.text) .map((it: any) => it.text)
.join(','); .join(',') || '-'
);
} }
if (currentColumnData.type === 'MULTIPLE_INPUT') { if (currentColumnData.type === 'MULTIPLE_INPUT') {
// 处理标签形式 // 处理标签形式
return JSON.parse(currentColumnData.defaultValue).join(''); return JSON.parse(currentColumnData.defaultValue).join('') || '-';
} }
if (selectExcludes.includes(currentColumnData.type)) { if (selectExcludes.includes(currentColumnData.type)) {
return currentColumnData.options return (
(currentColumnData.options || [])
.filter((item: any) => currentColumnData.defaultValue === item.value) .filter((item: any) => currentColumnData.defaultValue === item.value)
.map((it: any) => it.text) .map((it: any) => it.text)
.join(); .join() || '-'
);
} }
return currentColumnData.defaultValue; return currentColumnData.defaultValue || '-';
} }
} }

View File

@ -7,7 +7,13 @@
<span class="text-[14px]">{{ t('project.messageManagement.notRemind') }}</span> <span class="text-[14px]">{{ t('project.messageManagement.notRemind') }}</span>
</template> </template>
</a-alert> </a-alert>
<a-button v-permission="['PROJECT_MESSAGE:READ+ADD']" type="primary" class="mb-[16px]" @click="handleCreateClick"> <a-button
v-xpack
v-permission="['PROJECT_MESSAGE:READ+ADD']"
type="primary"
class="mb-[16px]"
@click="handleCreateClick"
>
{{ t('project.messageManagement.createBot') }} {{ t('project.messageManagement.createBot') }}
</a-button> </a-button>
<div <div

View File

@ -108,7 +108,7 @@
.detail-info { .detail-info {
height: 100%; height: 100%;
background: url('@/assets/images/basic_bg.png'); background: url('@/assets/images/basic_bg.png');
background-size: auto; background-size: cover;
.button { .button {
border-radius: 2px; border-radius: 2px;
@apply inline-block px-2 py-1 text-xs; @apply inline-block px-2 py-1 text-xs;

View File

@ -113,6 +113,7 @@
import useModal from '@/hooks/useModal'; import useModal from '@/hooks/useModal';
import { useAppStore, useTableStore } from '@/store'; import { useAppStore, useTableStore } from '@/store';
import { characterLimit } from '@/utils'; import { characterLimit } from '@/utils';
import { hasAnyPermission } from '@/utils/permission';
import type { import type {
ActionProjectMember, ActionProjectMember,
@ -346,6 +347,9 @@
// //
const changeUser = (record: ProjectMemberItem) => { const changeUser = (record: ProjectMemberItem) => {
if (!hasAnyPermission(['PROJECT_USER:READ+UPDATE'])) {
return;
}
if (record.enable) { if (record.enable) {
record.showUserSelect = true; record.showUserSelect = true;
record.selectUserList = (record.userRoles || []).map((item) => item.id); record.selectUserList = (record.userRoles || []).map((item) => item.id);

View File

@ -27,7 +27,7 @@
v-on="propsEvent" v-on="propsEvent"
@batch-action="handleTableBatch" @batch-action="handleTableBatch"
> >
<template #project="{ record }"> <template #projectIdNameMap="{ record }">
<MsTagGroup <MsTagGroup
v-if="!record.showProjectSelect" v-if="!record.showProjectSelect"
:tag-list="record.projectIdNameMap || []" :tag-list="record.projectIdNameMap || []"
@ -47,9 +47,9 @@
> >
<a-option v-for="item of projectOptions" :key="item.id" :value="item.id">{{ item.name }}</a-option> <a-option v-for="item of projectOptions" :key="item.id" :value="item.id">{{ item.name }}</a-option>
</a-select> </a-select>
<span v-if="(record.selectProjectList || []).length === 0">-</span> <span v-if="(record.projectIdNameMap || []).length === 0">-</span>
</template> </template>
<template #userRole="{ record }"> <template #userRoleIdNameMap="{ record }">
<MsTagGroup <MsTagGroup
v-if="!record.showUserSelect" v-if="!record.showUserSelect"
:tag-list="record.userRoleIdNameMap || []" :tag-list="record.userRoleIdNameMap || []"
@ -69,7 +69,7 @@
> >
<a-option v-for="item of userGroupOptions" :key="item.id" :value="item.id">{{ item.name }}</a-option> <a-option v-for="item of userGroupOptions" :key="item.id" :value="item.id">{{ item.name }}</a-option>
</a-select> </a-select>
<span v-if="(record.selectUserList || []).length === 0">-</span> <span v-if="(record.userRoleIdNameMap || []).length === 0">-</span>
</template> </template>
<template #enable="{ record }"> <template #enable="{ record }">
<div v-if="record.enable" class="flex items-center"> <div v-if="record.enable" class="flex items-center">
@ -142,6 +142,7 @@
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import { useAppStore, useTableStore } from '@/store'; import { useAppStore, useTableStore } from '@/store';
import { characterLimit } from '@/utils'; import { characterLimit } from '@/utils';
import { hasAnyPermission } from '@/utils/permission';
import type { AddOrUpdateMemberModel, BatchAddProjectModel, LinkList, MemberItem } from '@/models/setting/member'; import type { AddOrUpdateMemberModel, BatchAddProjectModel, LinkList, MemberItem } from '@/models/setting/member';
import { TableKeyEnum } from '@/enums/tableEnum'; import { TableKeyEnum } from '@/enums/tableEnum';
@ -150,7 +151,6 @@
const appStore = useAppStore(); const appStore = useAppStore();
const { t } = useI18n(); const { t } = useI18n();
const lastOrganizationId = computed(() => appStore.currentOrgId); const lastOrganizationId = computed(() => appStore.currentOrgId);
const columns: MsTableColumn = [ const columns: MsTableColumn = [
{ {
title: 'organization.member.tableColunmEmail', title: 'organization.member.tableColunmEmail',
@ -181,18 +181,16 @@
}, },
{ {
title: 'organization.member.tableColunmPro', title: 'organization.member.tableColunmPro',
slotName: 'project', slotName: 'projectIdNameMap',
dataIndex: 'projectIdNameMap', dataIndex: 'projectIdNameMap',
showInTable: true, showInTable: true,
isTag: true,
showDrag: true, showDrag: true,
}, },
{ {
title: 'organization.member.tableColunmUsergroup', title: 'organization.member.tableColunmUsergroup',
slotName: 'userRole', slotName: 'userRoleIdNameMap',
dataIndex: 'userRoleIdNameMap', dataIndex: 'userRoleIdNameMap',
showInTable: true, showInTable: true,
isTag: true,
showDrag: true, showDrag: true,
}, },
{ {
@ -347,6 +345,9 @@
}; };
// //
const changeUserOrProject = (record: MemberItem, type: string) => { const changeUserOrProject = (record: MemberItem, type: string) => {
if (!hasAnyPermission(['ORGANIZATION_MEMBER:READ+UPDATE'])) {
return;
}
if (!record.enable) { if (!record.enable) {
return; return;
} }
@ -362,6 +363,9 @@
}; };
// //
const selectUserOrProject = (value: any, record: MemberItem, type: string) => { const selectUserOrProject = (value: any, record: MemberItem, type: string) => {
if (!hasAnyPermission(['PROJECT_USER:READ+UPDATE'])) {
return;
}
if (type === 'project') { if (type === 'project') {
record.selectProjectList = value; record.selectProjectList = value;
} else { } else {