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) { export function getExportConfig(projectId: string) {
return MSR.get({ url: `${bugURL.getExportConfigUrl}${projectId}` }); return MSR.get({ url: `${bugURL.getExportConfigUrl}${projectId}` });
} }
// 获取模详情 // 获取模详情
export function getTemplateDetailInfo(data: { id: string; projectId: string }) { export function getTemplateDetailInfo(data: { id: string; projectId: string }) {
return MSR.post({ url: `${bugURL.getTemplateDetailUrl}`, data }); return MSR.post({ url: `${bugURL.getTemplateDetailUrl}`, data });
} }

View File

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

View File

@ -52,13 +52,13 @@ import type {
} from '@/models/setting/template'; } from '@/models/setting/template';
/** * /** *
* () * ()
*/ */
// 获取模列表(组织) // 获取模列表(组织)
export function getOrganizeTemplateList(params: TableQueryParams) { export function getOrganizeTemplateList(params: TableQueryParams) {
return MSR.get({ url: `${GetOrganizeTemplateUrl}/${params.organizationId}/${params.scene}` }); return MSR.get({ url: `${GetOrganizeTemplateUrl}/${params.organizationId}/${params.scene}` });
} }
// 获取模详情(组织) // 获取模详情(组织)
export function getOrganizeTemplateInfo(id: string) { export function getOrganizeTemplateInfo(id: string) {
return MSR.get({ url: `${GetOrganizeTemplateDetailUrl}/${id}` }); return MSR.get({ url: `${GetOrganizeTemplateDetailUrl}/${id}` });
} }
@ -176,13 +176,13 @@ export function getProjectFieldDetail(id: string) {
} }
/** * /** *
* () * ()
*/ */
// 获取模列表(项目) // 获取模列表(项目)
export function getProjectTemplateList(params: TableQueryParams) { export function getProjectTemplateList(params: TableQueryParams) {
return MSR.get({ url: `${GetProjectTemplateUrl}/${params.projectId}/${params.scene}` }); return MSR.get({ url: `${GetProjectTemplateUrl}/${params.projectId}/${params.scene}` });
} }
// 获取模详情(项目) // 获取模详情(项目)
export function getProjectTemplateInfo(id: string) { export function getProjectTemplateInfo(id: string) {
return MSR.get({ url: `${GetProjectTemplateDetailUrl}/${id}` }); 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 GetTrashCaseModuleTreeUrl = '/functional/case/module/trash/tree';
// 删除模块 // 删除模块
export const DeleteCaseModuleTreeUrl = '/functional/case/module/delete'; export const DeleteCaseModuleTreeUrl = '/functional/case/module/delete';
// 获取默认模自定义字段 // 获取默认模自定义字段
export const GetDefaultTemplateFieldsUrl = '/functional/case/default/template/field'; 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 SaveMessageUrl = '/notice/message/task/save'; // 保存消息配置
export const GetMessageUrl = '/notice/message/task/get'; // 获取消息配置列表 export const GetMessageUrl = '/notice/message/task/get'; // 获取消息配置列表
export const GetMessageUserListUrl = '/notice/message/task/get/user'; // 获取消息配置-用户列表 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'; // 获取消息配置详情 export const GetMessageDetailUrl = '/notice/message/template/detail'; // 获取消息配置详情

View File

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

View File

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

View File

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

View File

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

View File

@ -77,6 +77,7 @@
import MsDrawer from '@/components/pure/ms-drawer/index.vue'; import MsDrawer from '@/components/pure/ms-drawer/index.vue';
import type { MsTableColumn } from '@/components/pure/ms-table/type'; 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 ScriptDefined from './scriptDefined.vue';
import paramTable from '@/views/api-test/components/paramTable.vue'; import paramTable from '@/views/api-test/components/paramTable.vue';

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -45,8 +45,10 @@
</div> </div>
</template> </template>
<template v-else> <template v-else>
<div class="ms-upload-main-text"> <div class="ms-upload-main-text w-full">
{{ fileList[0]?.name }} <a-tooltip :content="fileList[0]?.name">
<span class="one-line-text w-[80%]"> {{ fileList[0]?.name }}</span>
</a-tooltip>
</div> </div>
<div class="ms-upload-sub-text">{{ formatFileSize(fileList[0]?.file?.size || 0) }}</div> <div class="ms-upload-sub-text">{{ formatFileSize(fileList[0]?.file?.size || 0) }}</div>
</template> </template>
@ -89,6 +91,7 @@
draggable: boolean; // draggable: boolean; //
isAllScreen?: boolean; // isAllScreen?: boolean; //
cutHeight: number; // cutHeight: number; //
fileTypeTip?: string; //
}> & { }> & {
accept: UploadType; accept: UploadType;
fileList: MsFileItem[]; fileList: MsFileItem[];
@ -132,6 +135,17 @@
Message.warning(t('ms.upload.overSize')); Message.warning(t('ms.upload.overSize'));
return Promise.resolve(false); 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); return Promise.resolve(true);
} }

View File

@ -15,4 +15,5 @@ export default {
'ms.upload.uploading': 'Waiting/Uploading', 'ms.upload.uploading': 'Waiting/Uploading',
'ms.upload.success': 'Success', 'ms.upload.success': 'Success',
'ms.upload.detail': 'Detail', '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.success': '成功',
'ms.upload.fail': '失败', 'ms.upload.fail': '失败',
'ms.upload.detail': '查看详情', 'ms.upload.detail': '查看详情',
'ms.upload.fileTypeValidate': '仅支持 {type} 格式的文件',
}; };

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -67,7 +67,7 @@ const ProjectManagement: AppRouteRecordRaw = {
component: () => import('@/views/project-management/projectAndPermission/basicInfos/index.vue'), component: () => import('@/views/project-management/projectAndPermission/basicInfos/index.vue'),
meta: { meta: {
locale: 'project.permission.basicInfo', 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, name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_TEMPLATE_FIELD_SETTING,
locale: 'menu.settings.organization.templateFieldSetting', locale: 'menu.settings.organization.templateFieldSetting',
editLocale: 'menu.settings.organization.templateFieldSetting', editLocale: 'menu.settings.organization.templateFieldSetting',
query: ['type'],
}, },
], ],
}, },
@ -169,6 +170,7 @@ const ProjectManagement: AppRouteRecordRaw = {
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_TEMPLATE_MANAGEMENT, name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_TEMPLATE_MANAGEMENT,
locale: 'menu.settings.organization.templateManagementList', locale: 'menu.settings.organization.templateManagementList',
editLocale: 'menu.settings.organization.templateManagementList', editLocale: 'menu.settings.organization.templateManagementList',
query: ['type'],
}, },
], ],
}, },
@ -189,11 +191,13 @@ const ProjectManagement: AppRouteRecordRaw = {
{ {
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_TEMPLATE_MANAGEMENT, name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_TEMPLATE_MANAGEMENT,
locale: 'menu.settings.organization.templateManagementList', locale: 'menu.settings.organization.templateManagementList',
query: ['type'],
}, },
{ {
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_TEMPLATE_MANAGEMENT_DETAIL, name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_TEMPLATE_MANAGEMENT_DETAIL,
locale: 'menu.settings.organization.templateManagementDetail', locale: 'menu.settings.organization.templateManagementDetail',
editLocale: 'menu.settings.organization.templateManagementEdit', editLocale: 'menu.settings.organization.templateManagementEdit',
query: ['type'],
}, },
], ],
}, },
@ -214,6 +218,7 @@ const ProjectManagement: AppRouteRecordRaw = {
{ {
name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_TEMPLATE_MANAGEMENT_WORKFLOW, name: ProjectManagementRouteEnum.PROJECT_MANAGEMENT_TEMPLATE_MANAGEMENT_WORKFLOW,
locale: 'menu.settings.organization.templateManagementWorkFlow', 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 { SettingRouteEnum } from '@/enums/routeEnum';
import { DEFAULT_LAYOUT } from '../base'; import { DEFAULT_LAYOUT } from '../base';
import type { AppRouteRecordRaw } from '../types'; import type { AppRouteRecordRaw } from '../types';
// const licenseStore = useLicenseStore();
const Setting: AppRouteRecordRaw = { const Setting: AppRouteRecordRaw = {
path: '/setting', path: '/setting',
name: SettingRouteEnum.SETTING, name: SettingRouteEnum.SETTING,
@ -220,7 +216,7 @@ const Setting: AppRouteRecordRaw = {
isTopMenu: true, isTopMenu: true,
}, },
}, },
// 模板列表-模字段设置 // 模板列表-模字段设置
{ {
path: 'templateFiledSetting', path: 'templateFiledSetting',
name: SettingRouteEnum.SETTING_ORGANIZATION_TEMPLATE_FILED_SETTING, name: SettingRouteEnum.SETTING_ORGANIZATION_TEMPLATE_FILED_SETTING,
@ -237,11 +233,12 @@ const Setting: AppRouteRecordRaw = {
name: SettingRouteEnum.SETTING_ORGANIZATION_TEMPLATE_FILED_SETTING, name: SettingRouteEnum.SETTING_ORGANIZATION_TEMPLATE_FILED_SETTING,
locale: 'menu.settings.organization.templateFieldSetting', locale: 'menu.settings.organization.templateFieldSetting',
editLocale: 'menu.settings.organization.templateFieldSetting', editLocale: 'menu.settings.organization.templateFieldSetting',
query: ['type'],
}, },
], ],
}, },
}, },
// 模版管理-模版列表 // 模板管理-模板列表
{ {
path: 'templateManagement', path: 'templateManagement',
name: SettingRouteEnum.SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT, name: SettingRouteEnum.SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT,
@ -258,11 +255,12 @@ const Setting: AppRouteRecordRaw = {
name: SettingRouteEnum.SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT, name: SettingRouteEnum.SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT,
locale: 'menu.settings.organization.templateManagementList', locale: 'menu.settings.organization.templateManagementList',
editLocale: 'menu.settings.organization.templateManagementList', editLocale: 'menu.settings.organization.templateManagementList',
query: ['type'],
}, },
], ],
}, },
}, },
// 模板列表-模板管理-创建&编辑模 // 模板列表-模板管理-创建&编辑模
{ {
path: 'templateManagementDetail/:mode?', path: 'templateManagementDetail/:mode?',
name: SettingRouteEnum.SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT_DETAIL, name: SettingRouteEnum.SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT_DETAIL,
@ -278,12 +276,14 @@ const Setting: AppRouteRecordRaw = {
{ {
name: SettingRouteEnum.SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT, name: SettingRouteEnum.SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT,
locale: 'menu.settings.organization.templateManagementList', locale: 'menu.settings.organization.templateManagementList',
query: ['type'],
}, },
{ {
name: SettingRouteEnum.SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT, name: SettingRouteEnum.SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT,
locale: 'menu.settings.organization.templateManagementDetail', locale: 'menu.settings.organization.templateManagementDetail',
editTag: 'id', editTag: 'id',
editLocale: 'menu.settings.organization.templateManagementEdit', editLocale: 'menu.settings.organization.templateManagementEdit',
query: ['type'],
}, },
], ],
}, },
@ -304,6 +304,7 @@ const Setting: AppRouteRecordRaw = {
{ {
name: SettingRouteEnum.SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT_WORKFLOW, name: SettingRouteEnum.SETTING_ORGANIZATION_TEMPLATE_MANAGEMENT_WORKFLOW,
locale: 'menu.settings.organization.templateManagementWorkFlow', locale: 'menu.settings.organization.templateManagementWorkFlow',
query: ['type'],
}, },
], ],
}, },

View File

@ -474,3 +474,16 @@ export function parseCurlScript(curlScript: string): ParsedCurlOptions {
return options; 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 show-charset-change
read-only read-only
> >
<template #title> <template #rightTitle>
<a-button type="outline" class="arco-btn-outline--secondary p-[0_8px]" size="mini" @click="copyScript"> <a-button type="outline" class="arco-btn-outline--secondary p-[0_8px]" size="mini" @click="copyScript">
<template #icon> <template #icon>
<MsIcon type="icon-icon_copy_outlined" class="text-var(--color-text-4)" size="12" /> <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 { postProjectMemberByProjectId } from '@/api/modules/setting/organizationAndProject';
import { useI18n } from '@/hooks/useI18n'; import { useI18n } from '@/hooks/useI18n';
import { formatPhoneNumber } from '@/utils';
const { t } = useI18n(); const { t } = useI18n();
@ -101,14 +102,23 @@
{ title: 'system.organization.operation', slotName: 'operation' }, { title: 'system.organization.operation', slotName: 'operation' },
]; ];
const { propsRes, propsEvent, loadList, setKeyword } = useTable(postProjectMemberByProjectId, { const { propsRes, propsEvent, loadList, setKeyword } = useTable(
postProjectMemberByProjectId,
{
heightUsed: 240, heightUsed: 240,
columns: projectColumn, columns: projectColumn,
scroll: { x: '100%' }, scroll: { x: '100%' },
selectable: false, selectable: false,
noDisable: false, noDisable: false,
pageSimple: true, pageSimple: true,
}); },
(record) => {
return {
...record,
phone: formatPhoneNumber(record.phone || ''),
};
}
);
async function searchUser() { async function searchUser() {
setKeyword(keyword.value); setKeyword(keyword.value);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -7,13 +7,7 @@
<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 <a-button v-permission="['PROJECT_MESSAGE:READ+ADD']" type="primary" class="mb-[16px]" @click="handleCreateClick">
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
@ -115,6 +109,7 @@
{{ platform.name }} {{ platform.name }}
</div> </div>
<div <div
v-xpack
:class="['platform-card-custom', robotForm.platform === 'CUSTOM' ? 'platform-card--active' : '']" :class="['platform-card-custom', robotForm.platform === 'CUSTOM' ? 'platform-card--active' : '']"
@click="robotForm.platform = 'CUSTOM'" @click="robotForm.platform = 'CUSTOM'"
> >

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -27,7 +27,7 @@
// //
const updateBreadcrumbList = () => { const updateBreadcrumbList = () => {
const { breadcrumbList } = appStore; 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) { if (breadTitle) {
breadcrumbList[0].locale = breadTitle.name; breadcrumbList[0].locale = breadTitle.name;
appStore.setBreadcrumbList(breadcrumbList); appStore.setBreadcrumbList(breadcrumbList);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -16,13 +16,15 @@
> >
<div class="mb-6 text-sm"> <div class="mb-6 text-sm">
{{ t('system.plugin.uploadSuccessAfter') }} {{ 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') }} {{ t('system.plugin.platformAuthentication') }}
</div> </div>
<div> <div>
<a-space> <a-space>
<a-button type="primary" @click="continueAdd">{{ t('system.plugin.continueUpload') }}</a-button> <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') t('system.plugin.ServiceIntegration')
}}</a-button> }}</a-button>
<a-button type="secondary" @click="emits('close')">{{ t('system.plugin.backPluginList') }}</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 { useI18n } from '@/hooks/useI18n';
import useVisit from '@/hooks/useVisit'; import useVisit from '@/hooks/useVisit';
import { RouteEnum } from '@/enums/routeEnum';
const router = useRouter(); const router = useRouter();
const visitedKey = 'doNotShowAgain'; const visitedKey = 'doNotShowAgain';
const { t } = useI18n(); const { t } = useI18n();

View File

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

View File

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

View File

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

View File

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