fix(系统管理): 修改插件bug&模板bug

This commit is contained in:
xinxin.wu 2024-02-01 23:00:55 +08:00 committed by 刘瑞斌
parent 89e3ce9266
commit bcd1530cbc
74 changed files with 438 additions and 272 deletions

View File

@ -65,7 +65,7 @@ export function getTemplateById(data: TableQueryParams) {
export function getExportConfig(projectId: string) {
return MSR.get({ url: `${bugURL.getExportConfigUrl}${projectId}` });
}
// 获取模详情
// 获取模详情
export function getTemplateDetailInfo(data: { id: string; projectId: string }) {
return MSR.post({ url: `${bugURL.getTemplateDetailUrl}`, data });
}

View File

@ -134,7 +134,7 @@ export function getCaseList(data: TableQueryParams) {
export function deleteCaseRequest(data: DeleteCaseType) {
return MSR.post({ url: `${DeleteCaseUrl}`, data });
}
// 获取默认模自定义字段
// 获取默认模自定义字段
export function getCaseDefaultFields(projectId: string) {
return MSR.get({ url: `${GetDefaultTemplateFieldsUrl}/${projectId}` });
}

View File

@ -52,13 +52,13 @@ import type {
} from '@/models/setting/template';
/** *
* ()
* ()
*/
// 获取模列表(组织)
// 获取模列表(组织)
export function getOrganizeTemplateList(params: TableQueryParams) {
return MSR.get({ url: `${GetOrganizeTemplateUrl}/${params.organizationId}/${params.scene}` });
}
// 获取模详情(组织)
// 获取模详情(组织)
export function getOrganizeTemplateInfo(id: string) {
return MSR.get({ url: `${GetOrganizeTemplateDetailUrl}/${id}` });
}
@ -176,13 +176,13 @@ export function getProjectFieldDetail(id: string) {
}
/** *
* ()
* ()
*/
// 获取模列表(项目)
// 获取模列表(项目)
export function getProjectTemplateList(params: TableQueryParams) {
return MSR.get({ url: `${GetProjectTemplateUrl}/${params.projectId}/${params.scene}` });
}
// 获取模详情(项目)
// 获取模详情(项目)
export function getProjectTemplateInfo(id: string) {
return MSR.get({ url: `${GetProjectTemplateDetailUrl}/${id}` });
}

View File

@ -39,7 +39,7 @@ export const MoveCaseModuleTreeUrl = '/functional/case/module/move';
export const GetTrashCaseModuleTreeUrl = '/functional/case/module/trash/tree';
// 删除模块
export const DeleteCaseModuleTreeUrl = '/functional/case/module/delete';
// 获取默认模自定义字段
// 获取默认模自定义字段
export const GetDefaultTemplateFieldsUrl = '/functional/case/default/template/field';
// 回收站

View File

@ -7,5 +7,5 @@ export const DeleteRobotUrl = '/project/robot/delete'; // 删除机器人
export const SaveMessageUrl = '/notice/message/task/save'; // 保存消息配置
export const GetMessageUrl = '/notice/message/task/get'; // 获取消息配置列表
export const GetMessageUserListUrl = '/notice/message/task/get/user'; // 获取消息配置-用户列表
export const GetMessageFieldsUrl = '/notice/template/get/fields'; // 获取消息配置-模字段
export const GetMessageFieldsUrl = '/notice/template/get/fields'; // 获取消息配置-模字段
export const GetMessageDetailUrl = '/notice/message/template/detail'; // 获取消息配置详情

View File

@ -1,35 +1,35 @@
// 项目---模板
// 获取模列表
// 获取模列表
export const GetProjectTemplateUrl = '/project/template/list';
// 设置模
// 设置模
export const SetProjectTemplateUrl = '/project/template/set-default';
// 创建模
// 创建模
export const CreateProjectTemplateUrl = '/project/template/add';
// 更新模
// 更新模
export const UpdateProjectTemplateUrl = '/project/template/update';
// 获取模详情
// 获取模详情
export const GetProjectTemplateDetailUrl = '/project/template/get';
// 删除模
// 删除模
export const DeleteProjectTemplateUrl = '/project/template/delete';
// 是否启用项目模板
export const getProjectTemplateStateUrl = '/project/template/enable/config';
// 组织--- 模板
// 获取模列表
// 获取模列表
export const GetOrganizeTemplateUrl = '/organization/template/list';
// 设置模
// 设置模
export const SetOrganizeTemplateUrl = '/organization/template/set-default';
// 创建模
// 创建模
export const CreateOrganizeTemplateUrl = '/organization/template/add';
// 更新模
// 更新模
export const UpdateOrganizeTemplateUrl = '/organization/template/update';
// 获取模详情
// 获取模详情
export const GetOrganizeTemplateDetailUrl = '/organization/template/get';
// 删除模
// 删除模
export const DeleteOrganizeTemplateUrl = '/organization/template/delete';
// 关闭组织模板,开启项目模
// 关闭组织模板,开启项目模
export const EnableOrOffTemplateUrl = '/organization/template/disable';
// 获取所有模板状态
export const getOrdTemplateStateUrl = '/organization/template/enable/config';

View File

@ -128,6 +128,7 @@
</template>
<script lang="ts" setup>
import { defineModel } from 'vue';
import { useClipboard } from '@vueuse/core';
import { InputInstance, Message } from '@arco-design/web-vue';

View File

@ -5,6 +5,7 @@
:mask="true"
title-align="start"
class="ms-modal-upload ms-modal-medium"
@close="cancelBatch"
>
<template #title>
{{ batchTitle }}

View File

@ -49,6 +49,7 @@
}, true);
function jumpTo(crumb: BreadcrumbItem) {
debugger;
if (crumb.isBack && window.history.state.back) {
router.back();
} else {

View File

@ -77,6 +77,7 @@
import MsDrawer from '@/components/pure/ms-drawer/index.vue';
import type { MsTableColumn } from '@/components/pure/ms-table/type';
import MsTagsInput from '@/components/pure/ms-tags-input/index.vue';
import ScriptDefined from './scriptDefined.vue';
import paramTable from '@/views/api-test/components/paramTable.vue';

View File

@ -102,7 +102,7 @@
return '';
// API[JSON]
case 'new_api_request': {
// requestObj
// requestObj
const headers = new Map();
headers.set('Content-type', 'application/json');
return getCodeTemplate(innerLanguageType.value, { requestHeaders: headers });

View File

@ -290,7 +290,7 @@ function pythonCode(requestObj) {
return _pythonCodeTemplate(obj);
}
// 获取javaBeanshell代码模
// 获取javaBeanshell代码模
function _beanshellTemplate(obj) {
const {
requestHeaders = new Map(),
@ -410,7 +410,7 @@ function javaCode(requestObj) {
return _beanshellTemplate(requestObj);
}
// 获取js语言代码模
// 获取js语言代码模
function _jsTemplate(obj) {
const {
requestHeaders = new Map(),

View File

@ -2,6 +2,7 @@
import { compile, computed, defineComponent, h, ref } from 'vue';
import { RouteRecordRaw, useRoute, useRouter } from 'vue-router';
import { Message } from '@arco-design/web-vue';
import { cloneDeep } from 'lodash-es';
import MsAvatar from '@/components/pure/ms-avatar/index.vue';
import MsIcon from '@/components/pure/ms-icon-font/index.vue';
@ -140,7 +141,7 @@
}
const isActiveSwitchOrg = ref(false);
const personalMenus = [
const personalMenus = ref([
{
label: t('personal.info'),
icon: <MsIcon type="icon-icon-contacts" class="text-[var(--color-text-4)]" />,
@ -170,22 +171,34 @@
icon: <MsIcon type="icon-icon_into-item_outlined" class="text-[var(--color-text-4)]" />,
event: () => logout(),
},
];
]);
const copyPersonalMenus = ref(cloneDeep(personalMenus));
const licenseStore = useLicenseStore();
onBeforeMount(async () => {
if (!licenseStore.hasLicense()) {
personalMenus.splice(1, 1);
return;
}
const xPack = computed(() => licenseStore.hasLicense());
async function getOrgList() {
try {
const res = await getOrgOptions();
originOrgList.value = res || [];
} catch (error) {
// eslint-disable-next-line no-console
console.log(error);
}
});
}
watch(
() => xPack.value,
async (val) => {
if (val) {
personalMenus.value = [...copyPersonalMenus.value];
getOrgList();
} else {
personalMenus.value.splice(1, 1);
}
}
);
watch(
() => personalMenusVisible.value,
@ -207,7 +220,7 @@
v-slots={{
content: () => (
<div class="arco-trigger-menu-inner">
{personalMenus.map((e) => {
{personalMenus.value.map((e) => {
if (e.divider) {
return e.divider;
}

View File

@ -32,7 +32,7 @@
} from '@/api/modules/setting/usergroup';
import { useI18n } from '@/hooks/useI18n';
import { useAppStore } from '@/store';
import { characterLimit } from '@/utils';
import { characterLimit, formatPhoneNumber } from '@/utils';
import { hasAnyPermission } from '@/utils/permission';
import { CurrentUserGroupItem, UserTableItem } from '@/models/setting/usergroup';
@ -107,14 +107,23 @@
return postOrgUserByUserGroup;
};
const { propsRes, propsEvent, loadList, setLoadListParams, setKeyword } = useTable(getRequestBySystemType(), {
const { propsRes, propsEvent, loadList, setLoadListParams, setKeyword } = useTable(
getRequestBySystemType(),
{
columns: userGroupUsercolumns,
scroll: { x: '100%', minWidth: 700 },
selectable: false,
noDisable: true,
showSetting: false,
heightUsed: 288,
});
},
(record) => {
return {
...record,
phone: formatPhoneNumber(record.phone || ''),
};
}
);
const handlePermission = (permission: string[], cb: () => void) => {
if (!hasAnyPermission(permission)) {

View File

@ -26,11 +26,12 @@
size="small"
@change="(val) => handleThemeChange(val as Theme)"
/>
<slot name="leftTitle">
<span class="flex items-center gap-[4px] font-medium">{{ title }}</span>
</slot>
</div>
<div>
<slot name="title">
<span class="font-medium">{{ title }}</span>
</slot>
<slot name="rightTitle"> </slot>
<div
v-if="showFullScreen"
class="w-[96px] cursor-pointer text-right !text-[var(--color-text-4)]"

View File

@ -114,7 +114,7 @@
<script setup lang="ts">
/**
* @description 系统管理--模版管理-创建模板-添加字段到模板抽屉
* @description 系统管理--模板管理-创建模板-添加字段到模板抽屉
*/
import { computed, ref } from 'vue';
import { VueDraggable } from 'vue-draggable-plus';

View File

@ -45,8 +45,10 @@
</div>
</template>
<template v-else>
<div class="ms-upload-main-text">
{{ fileList[0]?.name }}
<div class="ms-upload-main-text w-full">
<a-tooltip :content="fileList[0]?.name">
<span class="one-line-text w-[80%]"> {{ fileList[0]?.name }}</span>
</a-tooltip>
</div>
<div class="ms-upload-sub-text">{{ formatFileSize(fileList[0]?.file?.size || 0) }}</div>
</template>
@ -89,6 +91,7 @@
draggable: boolean; //
isAllScreen?: boolean; //
cutHeight: number; //
fileTypeTip?: string; //
}> & {
accept: UploadType;
fileList: MsFileItem[];
@ -132,6 +135,17 @@
Message.warning(t('ms.upload.overSize'));
return Promise.resolve(false);
}
const fileFormatMatch = file.name.match(/\.([a-zA-Z0-9]+)$/);
//
const fileFormatType = fileFormatMatch ? fileFormatMatch[1] : 'none';
if (props.accept !== fileFormatType && props.accept !== 'none') {
Message.error(
props.fileTypeTip ? props?.fileTypeTip : t('ms.upload.fileTypeValidate', { type: props.accept.toUpperCase() })
);
return Promise.resolve(false);
}
return Promise.resolve(true);
}

View File

@ -15,4 +15,5 @@ export default {
'ms.upload.uploading': 'Waiting/Uploading',
'ms.upload.success': 'Success',
'ms.upload.detail': 'Detail',
'ms.upload.fileTypeValidate': 'Only files in {type} format are supported',
};

View File

@ -15,4 +15,5 @@ export default {
'ms.upload.success': '成功',
'ms.upload.fail': '失败',
'ms.upload.detail': '查看详情',
'ms.upload.fileTypeValidate': '仅支持 {type} 格式的文件',
};

View File

@ -155,7 +155,7 @@
async function initProjects() {
try {
if (appStore.currentOrgId && hasAnyPermission(['PROJECT_BASE_INFO:READ'])) {
if (appStore.currentOrgId && hasAnyPermission(['SYSTEM_PARAMETER_SETTING_BASE:READ'])) {
const res = await getProjectList(appStore.getCurrentOrgId);
projectList.value = res;
} else {

View File

@ -302,7 +302,7 @@ export const pathMap: PathMapItem[] = [
level: MENU_LEVEL[1],
},
{
key: 'SETTING_ORGANIZATION_TEMPLATE', // 系统设置-组织-模
key: 'SETTING_ORGANIZATION_TEMPLATE', // 系统设置-组织-模
locale: 'menu.settings.organization.template',
route: RouteEnum.SETTING_ORGANIZATION_TEMPLATE,
permission: [],

View File

@ -1,4 +1,4 @@
// 模展示字段icon
// 模展示字段icon
export enum TemplateIconEnum {
INPUT = 'icon-icon_input', // 输入框
TEXTAREA = 'icon-icon_style_one', // 文本
@ -17,9 +17,9 @@ export enum TemplateIconEnum {
SYSTEM = 'icon-icon_pound',
}
// 模列表图标卡片icon
// 模列表图标卡片icon
export enum TemplateCardEnum {
FUNCTIONAL = 'caseTemplate', // 用例模
FUNCTIONAL = 'caseTemplate', // 用例模
API = 'api_ui_Template', // API模板
UI = 'uiTemplate', // UI模板
TEST_PLAN = 'testPlanTemplate', // 测试计划模板

View File

@ -70,9 +70,9 @@ export default {
'menu.settings.organization.template': '模板',
'menu.settings.organization.bugTemplate': '缺陷模板',
'menu.settings.organization.templateFieldSetting': '字段设置',
'menu.settings.organization.templateManagementList': '模列表',
'menu.settings.organization.templateManagementDetail': '创建模',
'menu.settings.organization.templateManagementCopy': '复制模',
'menu.settings.organization.templateManagementList': '模列表',
'menu.settings.organization.templateManagementDetail': '创建模',
'menu.settings.organization.templateManagementCopy': '复制模',
'menu.settings.organization.templateManagementEdit': '更新模板',
'menu.settings.organization.templateManagementWorkFlow': '工作流设置',
'menu.settings.organization.log': '日志',

View File

@ -42,14 +42,14 @@ export interface ProjectRobotConfig {
type?: ProjectRobotDingTalkType; // 钉钉机器人类型
dingType?: ProjectRobotDingTalkType; // 钉钉机器人类型
enable: boolean; // 消息配置机器人是否开启
template: string; // 消息配置机器人发送模
defaultTemplate: string; // 消息配置机器人默认发送模
useDefaultTemplate: boolean; // 消息配置机器人是否使用默认模
template: string; // 消息配置机器人发送模
defaultTemplate: string; // 消息配置机器人默认发送模
useDefaultTemplate: boolean; // 消息配置机器人是否使用默认模
previewSubject?: string; // 消息配置机器人预览邮件标题
previewTemplate?: string; // 消息配置机器人预览发送模
subject: string; // 消息模配置的标题
defaultSubject: string; // 消息模配置的默认标题
useDefaultSubject: boolean; // 消息模是否使用默认标题
previewTemplate?: string; // 消息配置机器人预览发送模
subject: string; // 消息模配置的标题
defaultSubject: string; // 消息模配置的默认标题
useDefaultSubject: boolean; // 消息模是否使用默认标题
}
// 消息配置接收人
@ -87,9 +87,9 @@ export interface SaveMessageTemplateParams {
testId?: string; // 具体测试的ID
robotId: string;
enable: boolean;
template: string; // 消息配置企业用户自定义的消息模
template: string; // 消息配置企业用户自定义的消息模
subject: string; // 消息配置企业用户自定义的邮件标题
useDefaultTemplate: boolean; // 是否使用默认模
useDefaultTemplate: boolean; // 是否使用默认模
useDefaultSubject: boolean; // 是否使用默认邮件标题
}
@ -99,12 +99,12 @@ export interface MessageTemplateDetail extends SaveMessageTemplateParams {
robotName: string; // 消息配置机器人名称
platform: ProjectRobotPlatform;
previewSubject?: string; // 消息配置机器人预览邮件标题
previewTemplate?: string; // 消息配置机器人预览发送模
defaultTemplate: string; // 消息配置机器人默认发送模
defaultSubject: string; // 消息模配置的默认标题
previewTemplate?: string; // 消息配置机器人预览发送模
defaultTemplate: string; // 消息配置机器人默认发送模
defaultSubject: string; // 消息模配置的默认标题
}
// 消息配置模字段
// 消息配置模字段
export interface Field {
id: string;
name: string;
@ -116,6 +116,6 @@ export interface FieldSource {
}
export interface FieldMap {
fieldList: Field[]; // 消息配置模字段列表
fieldSourceList: FieldSource[]; // 消息配置模字段来源列表
fieldList: Field[]; // 消息配置模字段列表
fieldSourceList: FieldSource[]; // 消息配置模字段来源列表
}

View File

@ -4,12 +4,12 @@ import type { FormItem, FormItemType, FormRuleItem } from '@/components/pure/ms-
import { FormRule } from '@form-create/arco-design';
// 模管理(组织)
// 模管理(组织)
export interface OrganizeTemplateItem {
id: string;
name: string;
remark: string; // 备注
internal: true; // 是否是内置模
internal: true; // 是否是内置模
updateTime: number;
createTime: number;
createUser: string;
@ -27,7 +27,7 @@ export interface FieldOptions {
fieldId?: string;
value: string | string[] | number | number[];
text: string;
internal?: boolean; // 是否是内置模
internal?: boolean; // 是否是内置模
}
// 自定义字段

View File

@ -67,7 +67,7 @@ const ProjectManagement: AppRouteRecordRaw = {
component: () => import('@/views/project-management/projectAndPermission/basicInfos/index.vue'),
meta: {
locale: 'project.permission.basicInfo',
roles: ['*'],
roles: ['SYSTEM_PARAMETER_SETTING_BASE:READ'],
},
},
// 菜单管理
@ -148,6 +148,7 @@ const ProjectManagement: AppRouteRecordRaw = {
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_TEMPLATE_FIELD_SETTING,
locale: 'menu.settings.organization.templateFieldSetting',
editLocale: 'menu.settings.organization.templateFieldSetting',
query: ['type'],
},
],
},
@ -169,6 +170,7 @@ const ProjectManagement: AppRouteRecordRaw = {
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_TEMPLATE_MANAGEMENT,
locale: 'menu.settings.organization.templateManagementList',
editLocale: 'menu.settings.organization.templateManagementList',
query: ['type'],
},
],
},
@ -189,11 +191,13 @@ const ProjectManagement: AppRouteRecordRaw = {
{
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_TEMPLATE_MANAGEMENT,
locale: 'menu.settings.organization.templateManagementList',
query: ['type'],
},
{
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_TEMPLATE_MANAGEMENT_DETAIL,
locale: 'menu.settings.organization.templateManagementDetail',
editLocale: 'menu.settings.organization.templateManagementEdit',
query: ['type'],
},
],
},
@ -214,6 +218,7 @@ const ProjectManagement: AppRouteRecordRaw = {
{
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_TEMPLATE_MANAGEMENT_WORKFLOW,
locale: 'menu.settings.organization.templateManagementWorkFlow',
query: ['type'],
},
],
},

View File

@ -1,12 +1,8 @@
// import useLicenseStore from '@/store/modules/setting/license';
import { SettingRouteEnum } from '@/enums/routeEnum';
import { DEFAULT_LAYOUT } from '../base';
import type { AppRouteRecordRaw } from '../types';
// const licenseStore = useLicenseStore();
const Setting: AppRouteRecordRaw = {
path: '/setting',
name: SettingRouteEnum.SETTING,
@ -220,7 +216,7 @@ const Setting: AppRouteRecordRaw = {
isTopMenu: true,
},
},
// 模板列表-模字段设置
// 模板列表-模字段设置
{
path: 'templateFiledSetting',
name: SettingRouteEnum.SETTING_ORGANIZATION_TEMPLATE_FILED_SETTING,
@ -237,11 +233,12 @@ const Setting: AppRouteRecordRaw = {
name: SettingRouteEnum.SETTING_ORGANIZATION_TEMPLATE_FILED_SETTING,
locale: 'menu.settings.organization.templateFieldSetting',
editLocale: 'menu.settings.organization.templateFieldSetting',
query: ['type'],
},
],
},
},
// 模版管理-模版列表
// 模板管理-模板列表
{
path: 'templateManagement',
name: SettingRouteEnum.SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT,
@ -258,11 +255,12 @@ const Setting: AppRouteRecordRaw = {
name: SettingRouteEnum.SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT,
locale: 'menu.settings.organization.templateManagementList',
editLocale: 'menu.settings.organization.templateManagementList',
query: ['type'],
},
],
},
},
// 模板列表-模板管理-创建&编辑模
// 模板列表-模板管理-创建&编辑模
{
path: 'templateManagementDetail/:mode?',
name: SettingRouteEnum.SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT_DETAIL,
@ -278,12 +276,14 @@ const Setting: AppRouteRecordRaw = {
{
name: SettingRouteEnum.SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT,
locale: 'menu.settings.organization.templateManagementList',
query: ['type'],
},
{
name: SettingRouteEnum.SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT,
locale: 'menu.settings.organization.templateManagementDetail',
editTag: 'id',
editLocale: 'menu.settings.organization.templateManagementEdit',
query: ['type'],
},
],
},
@ -304,6 +304,7 @@ const Setting: AppRouteRecordRaw = {
{
name: SettingRouteEnum.SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT_WORKFLOW,
locale: 'menu.settings.organization.templateManagementWorkFlow',
query: ['type'],
},
],
},

View File

@ -474,3 +474,16 @@ export function parseCurlScript(curlScript: string): ParsedCurlOptions {
return options;
}
/**
*
* @param phoneNumber
*/
export function formatPhoneNumber(phoneNumber = '') {
if (phoneNumber && phoneNumber.trim().length === 11) {
const cleanedNumber = phoneNumber.replace(/\D/g, '');
const formattedNumber = cleanedNumber.replace(/(\d{3})(\d{4})(\d{4})/, '$1 $2 $3');
return formattedNumber;
}
return phoneNumber;
}

View File

@ -99,7 +99,7 @@
show-charset-change
read-only
>
<template #title>
<template #rightTitle>
<a-button type="outline" class="arco-btn-outline--secondary p-[0_8px]" size="mini" @click="copyScript">
<template #icon>
<MsIcon type="icon-icon_copy_outlined" class="text-var(--color-text-4)" size="12" />

View File

@ -68,6 +68,7 @@
import { postProjectMemberByProjectId } from '@/api/modules/setting/organizationAndProject';
import { useI18n } from '@/hooks/useI18n';
import { formatPhoneNumber } from '@/utils';
const { t } = useI18n();
@ -101,14 +102,23 @@
{ title: 'system.organization.operation', slotName: 'operation' },
];
const { propsRes, propsEvent, loadList, setKeyword } = useTable(postProjectMemberByProjectId, {
const { propsRes, propsEvent, loadList, setKeyword } = useTable(
postProjectMemberByProjectId,
{
heightUsed: 240,
columns: projectColumn,
scroll: { x: '100%' },
selectable: false,
noDisable: false,
pageSimple: true,
});
},
(record) => {
return {
...record,
phone: formatPhoneNumber(record.phone || ''),
};
}
);
async function searchUser() {
setKeyword(keyword.value);

View File

@ -378,7 +378,7 @@
const formItem = ref<FormRuleItem[]>([]);
const fApi = ref<any>(null);
//
//
async function initDefaultFields() {
formRules.value = [];
try {

View File

@ -329,7 +329,7 @@
const isCover = ref<boolean>(false);
const validateLoading = ref<boolean>(false);
//
//
async function validateTemplate(files: FileItem[], cover: boolean) {
fileList.value = files;
isCover.value = cover;

View File

@ -54,7 +54,7 @@ export default {
'caseManagement.featureCase.generatingDependencies': '生成依赖关系',
'caseManagement.featureCase.addToPublic': '添加到公共用例库',
'caseManagement.featureCase.updateCase': '更新用例',
'caseManagement.featureCase.latestTemplate': '默认为最新模',
'caseManagement.featureCase.latestTemplate': '默认为最新模',
'caseManagement.featureCase.copyStep': '复制该步骤',
'caseManagement.featureCase.InsertStepsBefore': '在之前插入步骤',
'caseManagement.featureCase.afterInsertingSteps': '在之后插入步骤',
@ -209,19 +209,19 @@ export default {
'caseManagement.featureCase.dragOrClick': '拖拽或点击此区域选择文件',
'caseManagement.featureCase.onlyEXcelTip': '仅支持 xls/xlsx单个大小不超过 100M',
'caseManagement.featureCase.onlyXmindTip': '仅支持 xmind/类型 单个大小不超过 100M',
'caseManagement.featureCase.checkTemplate': '校验模',
'caseManagement.featureCase.checkTemplate': '校验模',
'caseManagement.featureCase.selectedRecoverCase': '勾选ID相同时覆盖原用例',
'caseManagement.featureCase.notSelectedRecoverCase': '不勾选ID已存在时跳过该用例',
'caseManagement.featureCase.cancelValidate': '取消校验',
'caseManagement.featureCase.cancelValidateSuccess': '取消校验成功',
'caseManagement.featureCase.importFailedCountTitle': '导入失败用例({number})',
'caseManagement.featureCase.beforeUploadTip': '上传前请先按 { type } 模中的格式编辑内容',
'caseManagement.featureCase.beforeUploadTip': '上传前请先按 { type } 模中的格式编辑内容',
'caseManagement.featureCase.downloadTemplate': '下载 {type} 模板',
'caseManagement.featureCase.selectVersion': '选择版本',
'caseManagement.featureCase.defaultSelectNewVersion': '默认选择最新版本',
'caseManagement.featureCase.isRecoverOriginCase': '用例 ID 相同时覆盖原用例',
'caseManagement.featureCase.importingUseCase': '正在导入用例',
'caseManagement.featureCase.verifyingTemplate': '正在校验模正确性',
'caseManagement.featureCase.verifyingTemplate': '正在校验模正确性',
'caseManagement.featureCase.successfulCheck': '成功校验',
'caseManagement.featureCase.failCheck': '校验失败',
'caseManagement.featureCase.caseCount': '条用例;',

View File

@ -450,7 +450,7 @@
label: t('caseManagement.caseReview.belongModule'),
value: res.moduleName || t('common.root'),
},
//
//
...res.customFields.map((e) => {
try {
const val =

View File

@ -11,14 +11,14 @@
<div class="form mt-[32px] min-w-[416px]">
<a-form ref="formRef" :model="userInfo" @submit="handleSubmit">
<!-- TOTO 第一版本暂时只考虑普通登录 -->
<!-- <a-form-item class="login-form-item" field="radio" hide-label>
<a-form-item class="login-form-item" field="radio" hide-label>
<a-radio-group v-model="userInfo.authenticate" type="button">
<a-radio value="LOCAL">{{ t('login.form.normalLogin') }}</a-radio>
<a-radio value="LDAP">LDAP</a-radio>
<a-radio value="OAuth2">{{ t('login.form.oauth2Test') }}</a-radio>
<a-radio value="OIDC 90">OIDC 90</a-radio>
<!-- <a-radio value="OAuth2">{{ t('login.form.oauth2Test') }}</a-radio>
<a-radio value="OIDC 90">OIDC 90</a-radio> -->
</a-radio-group>
</a-form-item> -->
</a-form-item>
<a-form-item
class="login-form-item"
field="username"

View File

@ -291,7 +291,7 @@ function pythonCode(requestObj) {
return _pythonCodeTemplate(obj);
}
// 获取javaBeanshell代码模
// 获取javaBeanshell代码模
function _beanshellTemplate(obj) {
const {
requestHeaders = new Map(),
@ -411,7 +411,7 @@ function javaCode(requestObj) {
return _beanshellTemplate(requestObj);
}
// 获取js语言代码模
// 获取js语言代码模
function _jsTemplate(obj) {
const {
requestHeaders = new Map(),

View File

@ -498,6 +498,7 @@
},
{
title: 'project.fileManagement.type',
slotName: 'fileType',
dataIndex: 'fileType',
width: 90,
},
@ -543,7 +544,6 @@
},
];
const tableStore = useTableStore();
tableStore.initColumn(TableKeyEnum.FILE_MANAGEMENT_FILE, columns, 'drawer');
const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector, resetPagination } = useTable(
getFileList,
{
@ -1200,6 +1200,8 @@
handleStorageModalCancel();
});
}
await tableStore.initColumn(TableKeyEnum.FILE_MANAGEMENT_FILE, columns, 'drawer');
</script>
<style lang="less" scoped>

View File

@ -269,14 +269,14 @@
robotId: e.id,
robotName: e.name,
enable: false,
previewTemplate: firstRobot.previewTemplate, //
template: firstRobot.defaultTemplate, //
defaultTemplate: firstRobot.defaultTemplate, //
useDefaultTemplate: true, // 使
previewSubject: firstRobot.previewSubject, //
subject: firstRobot.defaultSubject, //
defaultSubject: firstRobot.defaultSubject, //
useDefaultSubject: true, // 使
previewTemplate: firstRobot.previewTemplate, //
template: firstRobot.defaultTemplate, //
defaultTemplate: firstRobot.defaultTemplate, //
useDefaultTemplate: true, // 使
previewSubject: firstRobot.previewSubject, //
subject: firstRobot.defaultSubject, //
defaultSubject: firstRobot.defaultSubject, //
useDefaultSubject: true, // 使
};
}
});

View File

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

View File

@ -71,25 +71,25 @@ export default {
'project.messageManagement.internalRobot': '内部机器人',
'project.messageManagement.customRobot': '自定义机器人',
'project.messageManagement.larkRobotTip': '通过webhook将自定义服务的消息推送至飞书',
'project.messageManagement.editMessage': '更新模',
'project.messageManagement.editMessage': '更新模',
'project.messageManagement.messageScript': '消息脚本',
'project.messageManagement.scriptTip': '展示消息通知的具体内容,以及引用的消息变量',
'project.messageManagement.messageTemplate': '更新模',
'project.messageManagement.messageTemplate': '更新模',
'project.messageManagement.updatePreview': '更新预览',
'project.messageManagement.title': '标题',
'project.messageManagement.titlePlaceholder': '请输入通知标题',
'project.messageManagement.titleMax': '标题长度不能超过 64 个字符',
'project.messageManagement.content': '内容',
'project.messageManagement.contentTip': '点击添加左侧名称编辑通知模',
'project.messageManagement.contentTip': '点击添加左侧名称编辑通知模',
'project.messageManagement.contentMax': '内容长度不能超过 500 个字符',
'project.messageManagement.var': '变量',
'project.messageManagement.desc': '描述',
'project.messageManagement.saveSuccess': '模保存成功',
'project.messageManagement.saveSuccess': '模保存成功',
'project.messageManagement.enableRobotSuccess': '{name} 已启用',
'project.messageManagement.disableRobotSuccess': '{name} 已禁用',
'project.messageManagement.saveReceiverSuccess': '接收人修改成功',
'project.messageManagement.unsetReceiverTip': '启用机器人前请先设置消息接收人',
'project.messageManagement.receiverNotNull': '请最少设置一位消息接收人',
'project.messageManagement.unsetReceiversTip': '配置模前请先设置消息接收人',
'project.messageManagement.unsetReceiversTip': '配置模前请先设置消息接收人',
'project.messageManagement.noMatchField': '暂无匹配字段',
};

View File

@ -3,7 +3,7 @@ export default {
'project.permission.project': '项目',
'project.permission.basicInfo': '基本信息',
'project.permission.menuManagement': '应用管理',
'project.permission.templateManager': '模管理',
'project.permission.templateManager': '模管理',
'project.permission.projectVersion': '项目版本',
'project.permission.memberPermission': '成员权限',
'project.permission.member': '成员',

View File

@ -26,6 +26,7 @@
</div>
<MsBaseTable
v-bind="propsRes"
ref="memberTableRef"
:action-config="tableBatchActions"
@selected-change="handleTableSelect"
v-on="propsEvent"
@ -112,7 +113,7 @@
import { useI18n } from '@/hooks/useI18n';
import useModal from '@/hooks/useModal';
import { useAppStore, useTableStore } from '@/store';
import { characterLimit } from '@/utils';
import { characterLimit, formatPhoneNumber } from '@/utils';
import { hasAnyPermission } from '@/utils/permission';
import type {
@ -132,24 +133,22 @@
const columns: MsTableColumn = [
{
title: 'project.member.tableColumnName',
slotName: 'name',
dataIndex: 'name',
showInTable: true,
showTooltip: true,
sortIndex: 0,
ellipsis: true,
showDrag: false,
},
{
title: 'project.member.tableColumnEmail',
slotName: 'email',
dataIndex: 'email',
showInTable: true,
showTooltip: true,
showDrag: true,
},
{
title: 'project.member.tableColumnPhone',
slotName: 'phone',
dataIndex: 'phone',
showInTable: true,
showDrag: true,
width: 150,
},
@ -157,7 +156,6 @@
title: 'project.member.tableColumnUserGroup',
slotName: 'userRole',
dataIndex: 'userRoleIdNameMap',
showInTable: true,
showDrag: true,
width: 300,
},
@ -165,7 +163,6 @@
title: 'project.member.tableColumnStatus',
slotName: 'enable',
dataIndex: 'enable',
showInTable: true,
width: 150,
},
{
@ -174,7 +171,6 @@
fixed: 'right',
dataIndex: 'operation',
width: 100,
showInTable: true,
showDrag: false,
},
];
@ -200,7 +196,9 @@
tableSelected.value = selectArr;
};
const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector } = useTable(getProjectMemberList, {
const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector } = useTable(
getProjectMemberList,
{
tableKey: TableKeyEnum.PROJECT_MEMBER,
selectable: true,
showSetting: true,
@ -209,7 +207,14 @@
scroll: {
x: 1200,
},
});
},
(record) => {
return {
...record,
phone: formatPhoneNumber(record.phone || ''),
};
}
);
const searchParams = ref<SearchParams>({
filter: {
@ -275,7 +280,7 @@
if (lastProjectId.value && record.id) {
await removeProjectMember(lastProjectId.value, record.id);
Message.success(t('project.member.deleteMemberSuccess'));
loadList();
initData();
resetSelector();
}
} catch (error) {
@ -299,7 +304,7 @@
};
try {
await batchModalRef.value.batchRequestFun(addProjectUserGroup, params);
loadList();
initData();
resetSelector();
} catch (error) {
console.log(error);
@ -380,10 +385,12 @@
...userGroupOptions.value,
];
};
const memberTableRef = ref();
onMounted(() => {
initData();
initOptions();
memberTableRef.value.initColumn(columns);
});
tableStore.initColumn(TableKeyEnum.PROJECT_MEMBER, columns, 'drawer');
</script>

View File

@ -62,7 +62,7 @@
import { deleteUserFromUserGroup, postUserByUserGroup } from '@/api/modules/project-management/usergroup';
import { useI18n } from '@/hooks/useI18n';
import { characterLimit } from '@/utils';
import { characterLimit, formatPhoneNumber } from '@/utils';
export interface projectDrawerProps {
visible: boolean;
@ -103,14 +103,23 @@
{ title: 'system.organization.operation', slotName: 'operation' },
];
const { propsRes, propsEvent, loadList, setLoadListParams, setKeyword } = useTable(postUserByUserGroup, {
const { propsRes, propsEvent, loadList, setLoadListParams, setKeyword } = useTable(
postUserByUserGroup,
{
heightUsed: 240,
columns: projectColumn,
scroll: { x: '100%' },
selectable: false,
noDisable: false,
pageSimple: true,
});
},
(record) => {
return {
...record,
phone: formatPhoneNumber(record.phone || ''),
};
}
);
async function searchUser() {
setKeyword(keyword.value);

View File

@ -116,7 +116,7 @@
<script setup lang="ts">
/**
* @description 系统管理-项目--模版管理-创建&编辑
* @description 系统管理-项目--模板管理-创建&编辑
*/
import { ref } from 'vue';
import { useRoute, useRouter } from 'vue-router';
@ -351,12 +351,14 @@
//
const setBreadText = () => {
debugger;
const { breadcrumbList } = appStore;
const { firstBreadTitle, ThirdBreadTitle } = breadTitle.value;
if (firstBreadTitle) {
breadcrumbList[0].locale = firstBreadTitle;
if (appStore.breadcrumbList.length > 2) {
breadcrumbList[2].locale = ThirdBreadTitle;
// breadcrumbList[1].query = ['type'];
}
appStore.setBreadcrumbList(breadcrumbList);
}
@ -383,6 +385,7 @@
);
onMounted(() => {
debugger;
setBreadText();
getClassifyField();
if (!isEdit.value) {

View File

@ -27,7 +27,7 @@
//
const updateBreadcrumbList = () => {
const { breadcrumbList } = appStore;
const breadTitle = getCardList('project').find((item: any) => item.key === route.query.type);
const breadTitle = getCardList('project').find((item: any) => item.key === route.params.type);
if (breadTitle) {
breadcrumbList[0].locale = breadTitle.name;
appStore.setBreadcrumbList(breadcrumbList);

View File

@ -83,7 +83,7 @@
<script setup lang="ts">
/**
* @description 系统管理-项目--模版管理列表
* @description 系统管理-项目--模板管理列表
*/
import { ref } from 'vue';
import { useRoute } from 'vue-router';
@ -259,7 +259,7 @@
await loadList();
};
//
//
const changeDefault = async (value: any, record: OrdTemplateManagement) => {
if (value) {
try {
@ -350,7 +350,7 @@
defectForm.value = { ...initDetailForm };
};
//
//
const updateBreadcrumbList = () => {
const { breadcrumbList } = appStore;
const breadTitle = getCardList('project').find((item: any) => item.key === route.query.type);

View File

@ -11,7 +11,7 @@
<script setup lang="ts">
/**
* @description 项目管理--模版管理-工作流首页
* @description 项目管理--模板管理-工作流首页
*/
import MsCard from '@/components/pure/ms-card/index.vue';
import WorkflowTable from '@/views/setting/organization/template/components/workflowTable.vue';

View File

@ -27,7 +27,7 @@
<script setup lang="ts">
/**
* @description 项目设置--
* @description 项目设置--
*/
import { useRouter } from 'vue-router';

View File

@ -141,7 +141,7 @@
} from '@/api/modules/setting/member';
import { useI18n } from '@/hooks/useI18n';
import { useAppStore, useTableStore } from '@/store';
import { characterLimit } from '@/utils';
import { characterLimit, formatPhoneNumber } from '@/utils';
import { hasAnyPermission } from '@/utils/permission';
import type { AddOrUpdateMemberModel, BatchAddProjectModel, LinkList, MemberItem } from '@/models/setting/member';
@ -227,14 +227,23 @@
},
],
};
const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector } = useTable(getMemberList, {
const { propsRes, propsEvent, loadList, setLoadListParams, resetSelector } = useTable(
getMemberList,
{
tableKey: TableKeyEnum.ORGANIZATION_MEMBER,
scroll: { x: 1800 },
selectable: true,
heightUsed: 288,
showSetting: true,
size: 'default',
});
},
(record) => {
return {
...record,
phone: formatPhoneNumber(record.phone || ''),
};
}
);
const keyword = ref('');
const tableSelected = ref<(string | number)[]>([]);
//
@ -311,7 +320,7 @@
params.userRoleIds = target;
}
if (currentType) await batchModalRef.value.batchRequestFun(currentType.request, params);
loadList();
initData();
resetSelector();
};

View File

@ -26,7 +26,7 @@ export default {
'organization.member.deleteMemberTip': '确认移除 {name} 这个成员吗?',
'organization.member.deleteMemberConfirm': '确认删除',
'organization.member.deleteMemberCancel': '取消',
'organization.member.deleteMemberSuccess': '除成功',
'organization.member.deleteMemberSuccess': '除成功',
'organization.member.batchModalSuccess': '添加成功',
'organization.member.batchUpdateSuccess': '更新成功',
'organization.member.project': '项目',

View File

@ -61,6 +61,7 @@
import { deleteProjectMemberByOrg, postProjectMemberByProjectId } from '@/api/modules/setting/organizationAndProject';
import { useI18n } from '@/hooks/useI18n';
import { formatPhoneNumber } from '@/utils';
export interface projectDrawerProps {
visible: boolean;
@ -101,14 +102,23 @@
{ title: 'system.organization.operation', slotName: 'operation' },
];
const { propsRes, propsEvent, loadList, setLoadListParams, setKeyword } = useTable(postProjectMemberByProjectId, {
const { propsRes, propsEvent, loadList, setLoadListParams, setKeyword } = useTable(
postProjectMemberByProjectId,
{
heightUsed: 240,
columns: projectColumn,
scroll: { x: '100%' },
selectable: false,
noDisable: false,
pageSimple: true,
});
},
(record) => {
return {
...record,
phone: formatPhoneNumber(record.phone || ''),
};
}
);
async function searchUser() {
setKeyword(keyword.value);

View File

@ -1,7 +1,7 @@
export default {
'organization.service.searchPlugin': '通过插件名称搜索',
'organization.service.statusEnableTip': '开启:项目可以与该平台集成并生成该平台的默认模',
'organization.service.statusDisableTip': '关闭:项目无法与该平台集成且该平台默认模不可用',
'organization.service.statusEnableTip': '开启:项目可以与该平台集成并生成该平台的默认模',
'organization.service.statusDisableTip': '关闭:项目无法与该平台集成且该平台默认模不可用',
'organization.service.headerTip': '服务集成 使用指引',
'organization.service.integrationList': '集成列表',
'organization.service.packUp': '收起',
@ -38,7 +38,7 @@ export default {
'organization.service.confirmReset': '确认重置',
'organization.service.resetServiceTip': '确认重置 {name} 这个服务集成吗?',
'organization.service.resetServiceContentTip':
'重置后,集成信息将被清空,项目无法与该平台集成且该平台默认模不可用,谨慎操作!',
'重置后,集成信息将被清空,项目无法与该平台集成且该平台默认模不可用,谨慎操作!',
'organization.service.searchService': '通过插件名称搜索',
'organization.service.successMessage': '测试连接成功',
'organization.service.enableSuccess': '启用成功',

View File

@ -94,7 +94,7 @@
<script setup lang="ts">
/**
* @description 系统管理--模版管理-创建模板-添加字段到模板抽屉
* @description 系统管理--模板管理-创建模板-添加字段到模板抽屉
*/
import { ref } from 'vue';
import { VueDraggable } from 'vue-draggable-plus';

View File

@ -180,6 +180,7 @@
//
const showDateOrNumber = computed(() => {
selectFormat.value = getFieldType(fieldForm.value.type)[0].value;
if (fieldForm.value.type) return getFieldType(fieldForm.value.type);
});

View File

@ -38,7 +38,7 @@ const { t } = useI18n();
const templateStore = useTemplateStore();
// 字段类型-日期
const dateOptions = [
const dateOptions: { label: string; value: FormItemType }[] = [
{
label: dayjs().format('YYYY/MM/DD'),
value: 'DATE',
@ -50,7 +50,7 @@ const dateOptions = [
];
// 字段类型- 数字
const numberTypeOptions = [
const numberTypeOptions: { label: string; value: FormItemType }[] = [
{
label: '整数',
value: 'INT',
@ -62,16 +62,14 @@ const numberTypeOptions = [
];
// 获取字段类型是数值 || 日期
export const getFieldType = (selectFieldType: FormItemType) => {
export function getFieldType(selectFieldType: FormItemType): { label: string; value: FormItemType }[] {
switch (selectFieldType) {
case 'DATE':
return dateOptions;
case 'NUMBER':
return numberTypeOptions;
default:
break;
return numberTypeOptions;
}
};
}
const organizationState = computed(() => templateStore.ordStatus);
const projectState = computed(() => templateStore.projectStatus);
@ -91,18 +89,18 @@ export function getCardList(type: string): Record<string, any>[] {
value: TemplateCardEnum.API,
name: t('system.orgTemplate.APITemplates'),
},
{
id: 1003,
key: 'UI',
value: TemplateCardEnum.UI,
name: t('system.orgTemplate.UITemplates'),
},
{
id: 1004,
key: 'TEST_PLAN',
value: TemplateCardEnum.TEST_PLAN,
name: t('system.orgTemplate.testPlanTemplates'),
},
// {
// id: 1003,
// key: 'UI',
// value: TemplateCardEnum.UI,
// name: t('system.orgTemplate.UITemplates'),
// },
// {
// id: 1004,
// key: 'TEST_PLAN',
// value: TemplateCardEnum.TEST_PLAN,
// name: t('system.orgTemplate.testPlanTemplates'),
// },
{
id: 1005,
key: 'BUG',

View File

@ -127,7 +127,7 @@
<script setup lang="ts">
/**
* @description -字段列表
* @description -字段列表
*/
import { ref } from 'vue';
import { useRoute } from 'vue-router';
@ -273,7 +273,7 @@
: !templateStore.projectStatus[scene.value as string];
});
//
//
const isEnableOperation = () => {
if (isEnabledTemplate.value) {
const noOperationColumn = fieldColumns.slice(0, -1);

View File

@ -24,7 +24,7 @@
const route = useRoute();
const appStore = useAppStore();
//
//
const updateBreadcrumbList = () => {
const { breadcrumbList } = appStore;
const breadTitle = getCardList('organization').find((item: any) => item.key === route.query.type);

View File

@ -116,7 +116,7 @@
<script setup lang="ts">
/**
* @description 系统管理-组织--模版管理-创建&编辑
* @description 系统管理-组织--模板管理-创建&编辑
*/
import { ref } from 'vue';
import { useRoute, useRouter } from 'vue-router';

View File

@ -39,7 +39,7 @@
<script setup lang="ts">
/**
* @description -模版管理小卡片
* @description -模板管理小卡片
*/
import { ref } from 'vue';
import { Message } from '@arco-design/web-vue';

View File

@ -61,7 +61,7 @@
<script setup lang="ts">
/**
* @description 系统管理-组织--模版管理列表
* @description 系统管理-组织--模板管理列表
*/
import { ref } from 'vue';
import { useRoute } from 'vue-router';
@ -249,8 +249,9 @@
});
};
//
//
const updateBreadcrumbList = () => {
debugger;
const { breadcrumbList } = appStore;
const breadTitle = getCardList('organization').find((item: any) => item.key === route.query.type);
if (breadTitle) {

View File

@ -34,7 +34,7 @@
</div>
</template>
</MsBaseTable>
<!-- 添加字段到模抽屉 -->
<!-- 添加字段到模抽屉 -->
<AddFieldToTemplateDrawer
ref="fieldSelectRef"
v-model:visible="showDrawer"

View File

@ -37,7 +37,7 @@
<script setup lang="ts">
/**
* @description 系统设置--组织--
* @description 系统设置--组织--
*/
import { useRouter } from 'vue-router';
@ -77,7 +77,7 @@
const fieldSetting = (key: string) => {
router.push({
name: SettingRouteEnum.SETTING_ORGANIZATION_TEMPLATE_FILED_SETTING,
query: {
params: {
type: key,
},
});

View File

@ -10,28 +10,28 @@ export default {
'system.orgTemplate.edit': '编辑',
'system.orgTemplate.save': '保存',
'system.orgTemplate.templateDescription':
'模配置包含协作类型和事项类型组合配置。可应用于多个项目中,方便统一管理组织项目协作方式和工作流',
'模配置包含协作类型和事项类型组合配置。可应用于多个项目中,方便统一管理组织项目协作方式和工作流',
'system.orgTemplate.noReminders': '不再提醒',
'system.orgTemplate.caseTemplates': '用例模',
'system.orgTemplate.APITemplates': '接口模',
'system.orgTemplate.UITemplates': 'UI 模',
'system.orgTemplate.testPlanTemplates': '测试计划模',
'system.orgTemplate.defectTemplates': '缺陷模',
'system.orgTemplate.enabledTemplates': '已启用项目模',
'system.orgTemplate.disabledTemplates': '未启用项目模',
'system.orgTemplate.caseTemplates': '用例模',
'system.orgTemplate.APITemplates': '接口模',
'system.orgTemplate.UITemplates': 'UI 模',
'system.orgTemplate.testPlanTemplates': '测试计划模',
'system.orgTemplate.defectTemplates': '缺陷模',
'system.orgTemplate.enabledTemplates': '已启用项目模',
'system.orgTemplate.disabledTemplates': '未启用项目模',
'system.orgTemplate.fieldSetting': '字段设置',
'system.orgTemplate.TemplateManagement': '模管理',
'system.orgTemplate.TemplateManagement': '模管理',
'system.orgTemplate.workflowSetup': '工作流设置',
'system.orgTemplate.enable': '启用项目模',
'system.orgTemplate.enable': '启用项目模',
'system.orgTemplate.update': '更新字段',
'system.orgTemplate.addField': '新增字段',
'system.orgTemplate.createField': '添加字段',
'system.orgTemplate.enableDescription': '已启用项目模,字段设置不可操作',
'system.orgTemplate.enableDescription': '已启用项目模,字段设置不可操作',
'system.orgTemplate.fieldLimit': '最多可新增 20 个字段',
'system.orgTemplate.isSystem': '系统',
'system.orgTemplate.fieldList': '字段列表',
'system.orgTemplate.addOptions': '添加一个选项',
'system.orgTemplate.deleteTip': '该字段在模中已使用,删除后数据将会丢失,请谨慎操作!',
'system.orgTemplate.deleteTip': '该字段在模中已使用,删除后数据将会丢失,请谨慎操作!',
'system.orgTemplate.deleteTitle': '确认删除 {name} 吗?',
'system.orgTemplate.input': '输入框',
'system.orgTemplate.textarea': '文本',
@ -64,16 +64,16 @@ export default {
'system.orgTemplate.updateTip': '确认更新 {name} 吗?',
'system.orgTemplate.updateDescription': '更新后,使用该字段的{type}将同步更新',
'system.orgTemplate.confirm': '确定',
'system.orgTemplate.columnTemplateName': '模名称',
'system.orgTemplate.columnTemplateName': '模名称',
'system.orgTemplate.copy': '复制',
'system.orgTemplate.defaultValue': '默认值',
'system.orgTemplate.required': '是否必填',
'system.orgTemplate.enableTemplateTip': '已启用项目模版,组织模版不可操作',
'system.orgTemplate.enableTemplateTip': '已启用项目模板,组织模板不可操作',
'system.orgTemplate.templateList': '模板列表',
'system.orgTemplate.createTemplate': '创建模',
'system.orgTemplate.createTemplate': '创建模',
'system.orgTemplate.templatePreview': '模板预览',
'system.orgTemplate.templateName': '模板名称',
'system.orgTemplate.templateNamePlaceholder': '请输入模名称',
'system.orgTemplate.templateNamePlaceholder': '请输入模名称',
'system.orgTemplate.optionalField': '可选字段',
'system.orgTemplate.selectAll': '全选',
'system.orgTemplate.systemField': '系统字段',
@ -156,7 +156,7 @@ export default {
'system.orgTemplate.defectNameTip': '可为缺陷名称设置默认值,创建时统一使用',
'system.orgTemplate.defectContentTip': '可为缺陷内容设置默认值,创建时统一使用',
'system.orgTemplate.templateNameRules': '请输入模板名称',
'system.orgTemplate.deleteProjectTemplateTip': '删除后,该模版已有的用例会继承默认模版,确认删除吗?',
'system.orgTemplate.deleteProjectTemplateTip': '删除后,该模板已有的用例会继承默认模板,确认删除吗?',
'system.orgTemplate.moduleRuleTip': '请选择模块',
'system.orgTemplate.modules': '模块',
'system.orgTemplate.tags': '标签',

View File

@ -6,7 +6,7 @@
</div>
<a-radio-group v-model:model-value="activeType" type="button">
<a-radio value="log">{{ t('system.config.memoryCleanup.log') }}</a-radio>
<a-radio value="history">{{ t('system.config.memoryCleanup.history') }}</a-radio>
<a-radio v-xpack value="history">{{ t('system.config.memoryCleanup.history') }}</a-radio>
</a-radio-group>
<template v-if="activeType === 'log'">
<div class="mb-[8px] mt-[16px] flex items-center">
@ -21,7 +21,7 @@
<a-input-number
v-model:model-value="timeCount"
class="w-[130px]"
:disabled="saveLoading"
:disabled="saveLoading || !isHasAdminPermission"
:min="0"
@blur="() => saveConfig()"
>
@ -49,7 +49,7 @@
<a-input-number
v-model:model-value="historyCount"
class="w-[130px]"
:disabled="saveLoading"
:disabled="saveLoading || !isHasAdminPermission"
:min="0"
@blur="() => saveConfig()"
/>
@ -66,6 +66,7 @@
import { getCleanupConfig, saveCleanupConfig } from '@/api/modules/setting/config';
import { useI18n } from '@/hooks/useI18n';
import { useUserStore } from '@/store';
import { hasAnyPermission } from '@/utils/permission';
const userStore = useUserStore();
const { t } = useI18n();
@ -114,9 +115,16 @@
}
});
const isHasAdminPermission = computed(() => {
return userStore.isAdmin;
});
const saveLoading = ref(false);
async function saveConfig() {
if (!isHasAdminPermission) {
return;
}
saveLoading.value = true;
await saveCleanupConfig([
{

View File

@ -34,8 +34,12 @@
{ key: 'baseConfig', title: t('system.config.baseConfig'), permission: ['SYSTEM_PARAMETER_SETTING_BASE:READ'] },
{ key: 'pageConfig', title: t('system.config.pageConfig'), permission: ['SYSTEM_PARAMETER_SETTING_DISPLAY:READ'] },
// TODO
// { key: 'authConfig', title: t('system.config.authConfig'), permission: ['SYSTEM_PARAMETER_SETTING_AUTH:READ'] },
{ key: 'memoryCleanup', title: t('system.config.memoryCleanup'), permission: [] },
{ key: 'authConfig', title: t('system.config.authConfig'), permission: ['SYSTEM_PARAMETER_SETTING_AUTH:READ'] },
{
key: 'memoryCleanup',
title: t('system.config.memoryCleanup'),
permission: ['SYSTEM_PARAMETER_SETTING_MEMORY_CLEAN:READ'],
},
]);
watch(

View File

@ -53,7 +53,11 @@
:ellipsis="true"
:tooltip="true"
:width="150"
/>
>
<template #cell="{ record }">
{{ record.description || '-' }}
</template>
</a-table-column>
<a-table-column :title="t('system.plugin.tableColumnsStatus')">
<template #cell="{ record }">
<div v-if="record.enable" class="flex items-center">

View File

@ -5,8 +5,11 @@
:mask="false"
:footer="false"
:title="t('system.plugin.showScriptTitle', { name: props.config.title })"
unmount-on-close
@close="handleClose"
>
<div class="w-full">
<div class="w-full">
<MsCodeEditor
v-model:model-value="pluginScript"
title="JSON"
@ -14,7 +17,11 @@
height="calc(100vh - 155px)"
theme="MS-text"
:read-only="props.readOnly"
:show-theme-change="false"
:show-title-line="true"
/>
</div>
</div>
</MsDrawer>
</template>
@ -64,7 +71,7 @@
}
);
function handleClose() {
emit('update:value', pluginScript.value);
showScriptDrawer.value = false;
}
</script>

View File

@ -1,6 +1,18 @@
<template>
<a-modal v-model:visible="updateVisible" width="680px" title-align="start" class="ms-modal-form ms-modal-medium">
<template #title> {{ t('system.plugin.updateTitle', { name: title }) }}</template>
<a-modal
v-model:visible="updateVisible"
:mask="true"
:mask-closable="false"
width="680px"
title-align="start"
class="ms-modal-form ms-modal-medium"
>
<template #title>
<a-tooltip :content="title" position="right">
<span>{{ t('system.plugin.updateTitle') }}</span>
<span class="ml-1 !text-[var(--color-text-4)]"> ({{ characterLimit(title) }})</span>
</a-tooltip>
</template>
<div class="form">
<a-form ref="UpdateFormRef" :model="form" layout="vertical">
<a-form-item field="name" :label="t('system.plugin.name')" asterisk-position="end">
@ -44,7 +56,6 @@
v-model="form.description"
:max-length="1000"
:placeholder="t('system.plugin.pluginDescription')"
allow-clear
/>
</a-form-item>
</a-form>
@ -64,6 +75,7 @@
import { updatePlugin } from '@/api/modules/setting/pluginManger';
import { useI18n } from '@/hooks/useI18n';
import { characterLimit } from '@/utils';
import type { PluginItem, UpdatePluginModel } from '@/models/setting/plugin';
@ -113,10 +125,10 @@
if (!errors) {
confirmLoading.value = true;
try {
const { id, name, organizationIds, global, description } = form.value;
const { id, name, organizationIds, global, description, fileName } = form.value;
const params = {
id,
name: name || title.value,
name: name || fileName,
organizationIds,
global,
description,

View File

@ -1,5 +1,11 @@
<template>
<a-modal v-model:visible="pluginVisible" class="ms-modal-form ms-modal-small" title-align="start">
<a-modal
v-model:visible="pluginVisible"
class="ms-modal-form ms-modal-small"
title-align="start"
:mask="true"
:mask-closable="false"
>
<template #title> {{ t('system.plugin.uploadPlugin') }} </template>
<div class="form grid grid-cols-1">
<a-row class="grid-demo">
@ -64,7 +70,6 @@
v-model="form.description"
:max-length="1000"
:placeholder="t('system.plugin.pluginDescription')"
allow-clear
/>
</a-form-item>
</a-form>
@ -79,6 +84,7 @@
:show-file-list="false"
:auto-upload="false"
:disabled="confirmLoading"
:draggable="true"
></MsUpload>
</div>
<template #footer>
@ -109,7 +115,7 @@
>{{ t('system.plugin.saveAndAdd') }}</a-button
>
<a-button type="primary" :disabled="isDisabled" :loading="confirmLoading" @click="saveConfirm">{{
t('system.plugin.pluginConfirm')
t('common.save')
}}</a-button>
</div>
</div>
@ -125,11 +131,13 @@
import { addPlugin } from '@/api/modules/setting/pluginManger';
import { useI18n } from '@/hooks/useI18n';
import useVisit from '@/hooks/useVisit';
import type { FileItem, FormInstance, SelectOptionData, ValidatedError } from '@arco-design/web-vue';
const { t } = useI18n();
const visitedKey = 'doNotShowAgain';
const { getIsVisited } = useVisit(visitedKey);
const emits = defineEmits<{
(event: 'update:visible', visible: boolean): void;
(e: 'success'): void;
@ -193,7 +201,11 @@
fileList: [fileList.value[0].file],
};
await addPlugin(params);
const isOpen = getIsVisited();
if (isOpen) {
Message.success(t('system.plugin.uploadSuccessTip'));
}
if (flag === 'Confirm') {
emits('success');
handleCancel();

View File

@ -16,13 +16,15 @@
>
<div class="mb-6 text-sm">
{{ t('system.plugin.uploadSuccessAfter') }}
<a href="javascript:;">{{ t('system.plugin.ServiceIntegration') }}</a>
<a @click="router.push({ name: RouteEnum.SETTING_ORGANIZATION_SERVICE })">{{
t('system.plugin.ServiceIntegration')
}}</a>
{{ t('system.plugin.platformAuthentication') }}
</div>
<div>
<a-space>
<a-button type="primary" @click="continueAdd">{{ t('system.plugin.continueUpload') }}</a-button>
<a-button type="outline" @click="router.push({ name: 'settingOrganizationService' })">{{
<a-button type="outline" @click="router.push({ name: RouteEnum.SETTING_ORGANIZATION_SERVICE })">{{
t('system.plugin.ServiceIntegration')
}}</a-button>
<a-button type="secondary" @click="emits('close')">{{ t('system.plugin.backPluginList') }}</a-button>
@ -42,6 +44,8 @@
import { useI18n } from '@/hooks/useI18n';
import useVisit from '@/hooks/useVisit';
import { RouteEnum } from '@/enums/routeEnum';
const router = useRouter();
const visitedKey = 'doNotShowAgain';
const { t } = useI18n();

View File

@ -56,7 +56,7 @@ export default {
'system.plugin.pluginCancel': 'Cancel',
'system.plugin.pluginPreStep': 'Previous Step',
'system.plugin.saveAndAdd': 'Save & Continue',
'system.plugin.updateTitle': 'Update Plugin{name}',
'system.plugin.updateTitle': 'Update Plugin',
'system.plugin.selectOrganizeTip': 'Please Choose Organization',
'system.plugin.selectOrganization': 'Choose Organization',
'system.plugin.infoTip': 'Jump to the Github download plug-in',

View File

@ -43,7 +43,7 @@ export default {
'system.plugin.pluginCancel': '取消',
'system.plugin.pluginPreStep': '上一步',
'system.plugin.saveAndAdd': '保存并继续添加',
'system.plugin.updateTitle': '更新插件{name}',
'system.plugin.updateTitle': '更新插件',
'system.plugin.selectOrganizeTip': '请选择组织',
'system.plugin.selectOrganization': '选择组织',
'system.plugin.infoTip': '跳转至 GitHub 下载插件',
@ -61,7 +61,7 @@ export default {
'system.plugin.deletePluginSuccess': '删除成功',
'system.plugin.disablePluginSuccess': '禁用成功',
'system.plugin.enablePluginSuccess': '启用成功',
'system.plugin.disablePluginContent': '项目无法与该平台集成且该平台默认模不可用,谨慎操作!',
'system.plugin.disablePluginContent': '项目无法与该平台集成且该平台默认模不可用,谨慎操作!',
'system.plugin.alertDescribe':
'MeterSphere v2.10 LTS 版本支持 DevOps、API 导入、请求、项目管理、协议 类型的插件,具体支持插件请',
'system.plugin.viewTable': '查看表格',
@ -71,8 +71,8 @@ export default {
'system.plugin.dataList': '项数据',
'system.plugin.allOrganize': '全部组织',
'system.plugin.theOrganize': '指定组织',
'system.plugin.statusEnableTip': '开启:项目可以与该平台集成并生成该平台的默认模',
'system.plugin.statusDisableTip': '关闭:项目无法与该平台集成且该平台默认模不可用',
'system.plugin.statusEnableTip': '开启:项目可以与该平台集成并生成该平台的默认模',
'system.plugin.statusDisableTip': '关闭:项目无法与该平台集成且该平台默认模不可用',
'system.plugin.uploadSuccessTip': '上传成功',
'system.plugin.updateSuccessTip': '更新成功',
'system.plugin.uploadDefeatTip': '插件解析失败,请重新上传!',

View File

@ -109,11 +109,11 @@ export default {
'system.resourcePool.testResourceDTO.downloadDeployYamlTip': '请先填写命名空间 和 Deploy Name 再下载YAML文件',
'system.resourcePool.testResourceDTO.downloadDaemonsetYaml': 'Daemonset.yaml',
'system.resourcePool.testResourceDTO.downloadDeploymentYaml': 'Deployment.yaml',
'system.resourcePool.customJobTemplate': '自定义 Job 模',
'system.resourcePool.jobTemplate': 'Job 模',
'system.resourcePool.customJobTemplate': '自定义 Job 模',
'system.resourcePool.jobTemplate': 'Job 模',
'system.resourcePool.jobTemplateTip':
'Kubernetes Job 模版是一个YAML格式的文本用于定义Job的运行参数您可以在此处编辑Job模版。',
'system.resourcePool.jobTemplateReset': '重置 Job 模',
'Kubernetes Job 模板是一个YAML格式的文本用于定义Job的运行参数您可以在此处编辑Job模板。',
'system.resourcePool.jobTemplateReset': '重置 Job 模',
'system.resourcePool.addSuccess': '添加资源池成功',
'system.resourcePool.updateSuccess': '更新资源池成功',
};

View File

@ -222,7 +222,7 @@
import { useI18n } from '@/hooks/useI18n';
import useModal from '@/hooks/useModal';
import { useTableStore } from '@/store';
import { characterLimit } from '@/utils';
import { characterLimit, formatPhoneNumber } from '@/utils';
import { hasAnyPermission } from '@/utils/permission';
import { validateEmail, validatePhone } from '@/utils/validate';
@ -292,6 +292,7 @@
...record,
organizationList: record.organizationList.filter((e: any) => e),
userRoleList: record.userRoleList.filter((e: any) => e),
phone: formatPhoneNumber(record.phone || ''),
})
);
@ -647,7 +648,14 @@
visible.value = true;
userFormMode.value = mode;
if (mode === 'edit' && record) {
userForm.value.list = [{ id: record.id, name: record.name, email: record.email, phone: record.phone }];
userForm.value.list = [
{
id: record.id,
name: record.name,
email: record.email,
phone: record.phone ? record.phone.replace(/\s/g, '') : record.phone,
},
];
userForm.value.userGroup = record.userRoleList.map((e) => e.id);
}
}