feat(系统设置): 服务集成本地联调和插件&服务集成联动调试
This commit is contained in:
parent
6bd1f650b0
commit
cab07f4836
|
@ -30,8 +30,8 @@ export function getValidate(id: string) {
|
||||||
return MSR.get({ url: GetValidateServiceUrl, params: id });
|
return MSR.get({ url: GetValidateServiceUrl, params: id });
|
||||||
}
|
}
|
||||||
// 内部校验测试连接 注:不同的平台对应的不同的字段
|
// 内部校验测试连接 注:不同的平台对应的不同的字段
|
||||||
export function postValidate(data: any) {
|
export function postValidate(data: any, pluginId: string) {
|
||||||
return MSR.post({ url: PostValidateServiceUrl, data });
|
return MSR.post({ url: PostValidateServiceUrl, data, params: pluginId });
|
||||||
}
|
}
|
||||||
// 前端配置脚本
|
// 前端配置脚本
|
||||||
export function configScript(pluginId: string) {
|
export function configScript(pluginId: string) {
|
||||||
|
|
|
@ -3,6 +3,6 @@ export const AddServiceUrl = '/service/integration/add';
|
||||||
export const UpdateServiceUrl = '/service/integration/update';
|
export const UpdateServiceUrl = '/service/integration/update';
|
||||||
export const ResetServiceUrl = '/service/integration/delete';
|
export const ResetServiceUrl = '/service/integration/delete';
|
||||||
export const GetValidateServiceUrl = '/service/integration/validate';
|
export const GetValidateServiceUrl = '/service/integration/validate';
|
||||||
export const PostValidateServiceUrl = '/service/integration/validate';
|
export const PostValidateServiceUrl = '/service/integration/validate/';
|
||||||
export const ConfigServiceScriptUrl = '/service/integration/script/';
|
export const ConfigServiceScriptUrl = '/service/integration/script/';
|
||||||
export const getLogoUrl = '/plugin/image';
|
export const getLogoUrl = '/plugin/image';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
export interface ServiceItem {
|
export type ServiceItem = Partial<{
|
||||||
id?: string;
|
id?: string;
|
||||||
pluginId: string; // 插件id
|
pluginId: string; // 插件id
|
||||||
title: string;
|
title: string;
|
||||||
|
@ -8,16 +8,31 @@ export interface ServiceItem {
|
||||||
logo: string;
|
logo: string;
|
||||||
organizationId: string; // 组织id
|
organizationId: string; // 组织id
|
||||||
configuration?: null; // 配置项
|
configuration?: null; // 配置项
|
||||||
}
|
}>;
|
||||||
|
|
||||||
export type ServiceList = ServiceItem[];
|
export type ServiceList = ServiceItem[];
|
||||||
|
|
||||||
// 创建和更新服务
|
// 创建和更新服务
|
||||||
|
|
||||||
export interface AddOrUpdateServiceModel {
|
export type AddOrUpdateServiceModel = Partial<{
|
||||||
id?: string;
|
id?: string;
|
||||||
pluginId: string;
|
pluginId: string;
|
||||||
enable: boolean;
|
enable: boolean | undefined;
|
||||||
organizationId: string;
|
organizationId: string;
|
||||||
configuration: any;
|
configuration?: any;
|
||||||
|
}>;
|
||||||
|
|
||||||
|
export interface SkipTitle {
|
||||||
|
name: string;
|
||||||
|
src: string;
|
||||||
|
active: boolean; // 是否激活
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StepListType {
|
||||||
|
id: string;
|
||||||
|
icon: string;
|
||||||
|
title: string;
|
||||||
|
skipTitle: SkipTitle[];
|
||||||
|
step: string;
|
||||||
|
description: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,14 +6,14 @@
|
||||||
:ok-text="t('organization.member.Confirm')"
|
:ok-text="t('organization.member.Confirm')"
|
||||||
:cancel-text="t('organization.member.Cancel')"
|
:cancel-text="t('organization.member.Cancel')"
|
||||||
>
|
>
|
||||||
<template #title> 标题 </template>
|
<template #title> {{ title }} </template>
|
||||||
<div>
|
<div>
|
||||||
<MsFormCreate v-model:api="fApi" :rule="formRules" :option="options" />
|
<MsFormCreate v-model:api="fApi" :rule="formRules" :option="options" />
|
||||||
</div>
|
</div>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="flex justify-between">
|
<div class="flex justify-between">
|
||||||
<div class="flex flex-row items-center justify-center">
|
<div class="flex flex-row items-center justify-center">
|
||||||
<a-switch size="small" />
|
<a-switch v-model="isEnable" :disabled="isDisabled" size="small" />
|
||||||
<a-tooltip>
|
<a-tooltip>
|
||||||
<template #content>
|
<template #content>
|
||||||
<div class="text-sm">{{ t('organization.service.statusEnableTip') }}</div>
|
<div class="text-sm">{{ t('organization.service.statusEnableTip') }}</div>
|
||||||
|
@ -24,8 +24,12 @@
|
||||||
</div>
|
</div>
|
||||||
<a-space>
|
<a-space>
|
||||||
<a-button type="secondary" @click="handleCancel">{{ t('organization.service.Cancel') }}</a-button>
|
<a-button type="secondary" @click="handleCancel">{{ t('organization.service.Cancel') }}</a-button>
|
||||||
<a-button type="outline">{{ t('organization.service.testLink') }}</a-button>
|
<a-button type="outline" :loading="testLoading" @click="testLink">{{
|
||||||
<a-button type="primary" @click="saveHandler">{{ t('organization.service.Confirm') }}</a-button>
|
t('organization.service.testLink')
|
||||||
|
}}</a-button>
|
||||||
|
<a-button type="primary" :loading="loading" @click="saveHandler">{{
|
||||||
|
t('organization.service.Confirm')
|
||||||
|
}}</a-button>
|
||||||
</a-space>
|
</a-space>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -36,50 +40,28 @@
|
||||||
import { ref, watchEffect, watch } from 'vue';
|
import { ref, watchEffect, watch } from 'vue';
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
import MsFormCreate from '@/components/pure/ms-form-create/formCreate.vue';
|
import MsFormCreate from '@/components/pure/ms-form-create/formCreate.vue';
|
||||||
|
import { configScript, addOrUpdate, postValidate } from '@/api/modules/setting/serviceIntegration';
|
||||||
|
import { Message } from '@arco-design/web-vue';
|
||||||
|
import type { ServiceItem, AddOrUpdateServiceModel } from '@/models/setting/serviceIntegration';
|
||||||
|
import useLoading from '@/hooks/useLoading';
|
||||||
|
import { useUserStore } from '@/store';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
const userStore = useUserStore();
|
||||||
|
const lastOrganizationId = userStore.$state?.lastOrganizationId as string;
|
||||||
|
|
||||||
const emits = defineEmits<{
|
const emits = defineEmits<{
|
||||||
(event: 'update:visible', visible: boolean): void;
|
(event: 'update:visible', visible: boolean): void;
|
||||||
|
(event: 'success'): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
visible: boolean;
|
visible: boolean;
|
||||||
rule: any;
|
|
||||||
}>();
|
}>();
|
||||||
const detailVisible = ref<boolean>(false);
|
const detailVisible = ref<boolean>(false);
|
||||||
|
const { loading, setLoading } = useLoading(false);
|
||||||
|
|
||||||
const fApi = ref<any>({});
|
const fApi = ref<any>({});
|
||||||
const formRules = ref([]);
|
|
||||||
|
|
||||||
watchEffect(() => {
|
|
||||||
detailVisible.value = props.visible;
|
|
||||||
formRules.value = props.rule;
|
|
||||||
});
|
|
||||||
watch(
|
|
||||||
() => detailVisible.value,
|
|
||||||
(val) => {
|
|
||||||
emits('update:visible', val);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleCancel = () => {
|
|
||||||
detailVisible.value = false;
|
|
||||||
};
|
|
||||||
const submit = () => {
|
|
||||||
fApi.value?.submit((formData: FormData) => {
|
|
||||||
console.log(formData, 'formData');
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const saveHandler = () => {
|
|
||||||
fApi.value?.validate((valid: any, fail: any) => {
|
|
||||||
if (valid) {
|
|
||||||
submit();
|
|
||||||
} else {
|
|
||||||
console.log(fail);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const options = ref({
|
const options = ref({
|
||||||
resetBtn: false,
|
resetBtn: false,
|
||||||
submitBtn: false,
|
submitBtn: false,
|
||||||
|
@ -93,8 +75,118 @@
|
||||||
},
|
},
|
||||||
wrap: {
|
wrap: {
|
||||||
'asterisk-position': 'end',
|
'asterisk-position': 'end',
|
||||||
|
'validate-trigger': ['change'],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
const formRules = ref<any>([]);
|
||||||
|
const title = ref<string>('');
|
||||||
|
const formItem = ref<any>({});
|
||||||
|
watchEffect(() => {
|
||||||
|
detailVisible.value = props.visible;
|
||||||
|
});
|
||||||
|
watch(
|
||||||
|
() => detailVisible.value,
|
||||||
|
(val) => {
|
||||||
|
emits('update:visible', val);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const testLoading = ref<boolean>(false);
|
||||||
|
// 禁用
|
||||||
|
const isDisabled = ref<boolean>(false);
|
||||||
|
// 是否配置
|
||||||
|
const isConfigOrigin = ref<boolean | undefined>(false);
|
||||||
|
// 状态
|
||||||
|
const isEnable = ref<boolean | undefined>(false);
|
||||||
|
// 插件id
|
||||||
|
const pluginId = ref<string>('');
|
||||||
|
const type = ref<string>('');
|
||||||
|
|
||||||
|
const handleCancel = () => {
|
||||||
|
fApi.value.clearValidateState();
|
||||||
|
detailVisible.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const submit = () => {
|
||||||
|
fApi.value?.submit(async (formData: FormData) => {
|
||||||
|
setLoading(true);
|
||||||
|
try {
|
||||||
|
const params: AddOrUpdateServiceModel = {
|
||||||
|
id: type.value === 'edit' ? formItem.value.id : undefined,
|
||||||
|
pluginId: pluginId.value,
|
||||||
|
enable: isEnable.value,
|
||||||
|
organizationId: lastOrganizationId,
|
||||||
|
configuration: { ...formData },
|
||||||
|
};
|
||||||
|
const message =
|
||||||
|
type.value === 'edit' ? t('organization.service.updateSuccess') : t('organization.service.configSuccess');
|
||||||
|
await addOrUpdate(params, type.value);
|
||||||
|
Message.success(message);
|
||||||
|
handleCancel();
|
||||||
|
emits('success');
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const saveHandler = () => {
|
||||||
|
fApi.value?.validate((valid: any, fail: any) => {
|
||||||
|
if (valid) {
|
||||||
|
submit();
|
||||||
|
} else {
|
||||||
|
console.log(fail);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取配置脚本
|
||||||
|
const getPluginScript = async (cuurentPluginId: string) => {
|
||||||
|
try {
|
||||||
|
const result = await configScript(cuurentPluginId);
|
||||||
|
formRules.value = [...result];
|
||||||
|
if (type.value === 'edit') {
|
||||||
|
fApi.value.nextTick(() => {
|
||||||
|
fApi.value.setValue({ ...formItem.value.configuration });
|
||||||
|
fApi.value.refresh();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 测试连接是否通过
|
||||||
|
const testLink = async () => {
|
||||||
|
testLoading.value = true;
|
||||||
|
try {
|
||||||
|
const formValue = {
|
||||||
|
...fApi.value.formData(),
|
||||||
|
};
|
||||||
|
await postValidate(formValue, pluginId.value);
|
||||||
|
if (!isConfigOrigin.value) isDisabled.value = false;
|
||||||
|
Message.success(t('organization.service.successMessage'));
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
} finally {
|
||||||
|
testLoading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 创建&编辑
|
||||||
|
const addOrEdit = (serviceItem: ServiceItem) => {
|
||||||
|
type.value = serviceItem.config ? 'edit' : 'create';
|
||||||
|
isConfigOrigin.value = serviceItem.config;
|
||||||
|
isEnable.value = serviceItem.enable;
|
||||||
|
isDisabled.value = !serviceItem.config;
|
||||||
|
pluginId.value = serviceItem.pluginId as string;
|
||||||
|
formItem.value = { ...serviceItem };
|
||||||
|
getPluginScript(pluginId.value);
|
||||||
|
};
|
||||||
|
defineExpose({
|
||||||
|
addOrEdit,
|
||||||
|
title,
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
<template>
|
<template>
|
||||||
<MsCard simple class="mb-[16px]" auto-height>
|
<MsCard simple class="mb-[16px]" auto-height :loading="loading">
|
||||||
<div class="outer-wrapper">
|
<div class="outer-wrapper">
|
||||||
<div class="mb-[16px] flex justify-between">
|
<div class="mb-[16px] flex justify-between">
|
||||||
<div class="font-medium text-[var(--color-text-000)]">{{ t('organization.service.serviceIntegration') }}</div>
|
<div class="font-medium text-[var(--color-text-000)]">{{ t('organization.service.integrationList') }}</div>
|
||||||
<div>
|
<div>
|
||||||
<a-input-search
|
<a-input-search
|
||||||
v-model="keyword"
|
v-model="keyword"
|
||||||
:placeholder="t('organization.member.searchMember')"
|
:placeholder="t('organization.service.searchService')"
|
||||||
class="w-[230px]"
|
|
||||||
:max-length="250"
|
:max-length="250"
|
||||||
|
@search="searchHandler"
|
||||||
|
@press-enter="searchHandler"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -16,17 +17,19 @@
|
||||||
<a-scrollbar
|
<a-scrollbar
|
||||||
:style="{
|
:style="{
|
||||||
overflow: 'auto',
|
overflow: 'auto',
|
||||||
height: `calc(100vh - ${collapseHeight} - 220px)`,
|
height: `calc(100vh - ${collapseHeight} - 230px)`,
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<div class="list">
|
<div class="list">
|
||||||
<div v-for="item of data" :key="item.id" class="item">
|
<div v-for="item of filterList" :key="item.id" class="item">
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<span class="icon float-left mr-2 h-[40px] w-[40px]">{{ item.name }}</span>
|
<span class="icon float-left mr-2 h-[40px] w-[40px] rounded">
|
||||||
|
<img class="rounded" :src="`http://172.16.200.18:8081${item.logo}`" alt="log" />
|
||||||
|
</span>
|
||||||
<div class="flex flex-col justify-start">
|
<div class="flex flex-col justify-start">
|
||||||
<p>
|
<p>
|
||||||
<span class="mr-4 font-semibold">TAPD</span>
|
<span class="mr-4 font-semibold">{{ item.title }}</span>
|
||||||
<span v-if="!item.isConfig" class="ms-enable">{{ t('organization.service.unconfigured') }}</span>
|
<span v-if="!item.config" class="ms-enable">{{ t('organization.service.unconfigured') }}</span>
|
||||||
<span
|
<span
|
||||||
v-else
|
v-else
|
||||||
class="ms-enable active"
|
class="ms-enable active"
|
||||||
|
@ -37,30 +40,37 @@
|
||||||
>{{ t('organization.service.configured') }}</span
|
>{{ t('organization.service.configured') }}</span
|
||||||
>
|
>
|
||||||
</p>
|
</p>
|
||||||
<p class="mt-2 text-sm text-[var(--color-text-4)]">一站式敏捷研发协作云平台</p>
|
<p class="mt-2 text-sm text-[var(--color-text-4)]">{{ item.description }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-between">
|
<div class="flex justify-between">
|
||||||
<a-space>
|
<a-space>
|
||||||
<a-tooltip v-if="!item.isConfig" :content="t('organization.service.unconfiguredTip')" position="tl">
|
<a-tooltip v-if="!item.config" :content="t('organization.service.unconfiguredTip')" position="tl">
|
||||||
<span>
|
<span>
|
||||||
<a-button
|
<a-button
|
||||||
|
v-if="!item.config"
|
||||||
type="outline"
|
type="outline"
|
||||||
class="arco-btn-outline--secondary"
|
class="arco-btn-outline--secondary"
|
||||||
size="mini"
|
size="mini"
|
||||||
:disabled="!item.isConfig"
|
:disabled="!item.config"
|
||||||
|
@click="getValidateHandler(item)"
|
||||||
>{{ t('organization.service.testLink') }}</a-button
|
>{{ t('organization.service.testLink') }}</a-button
|
||||||
></span
|
></span
|
||||||
>
|
>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<a-button v-else type="outline" class="arco-btn-outline--secondary" size="mini">{{
|
<a-button
|
||||||
t('organization.service.testLink')
|
v-else
|
||||||
}}</a-button>
|
type="outline"
|
||||||
|
class="arco-btn-outline--secondary"
|
||||||
|
size="mini"
|
||||||
|
@click="getValidateHandler(item)"
|
||||||
|
>{{ t('organization.service.testLink') }}</a-button
|
||||||
|
>
|
||||||
<a-button type="outline" class="arco-btn-outline--secondary" size="mini" @click="editHandler(item)">{{
|
<a-button type="outline" class="arco-btn-outline--secondary" size="mini" @click="editHandler(item)">{{
|
||||||
t('organization.service.edit')
|
t('organization.service.edit')
|
||||||
}}</a-button>
|
}}</a-button>
|
||||||
<a-button
|
<a-button
|
||||||
v-if="item.isConfig"
|
v-if="item.config"
|
||||||
type="outline"
|
type="outline"
|
||||||
class="arco-btn-outline--secondary"
|
class="arco-btn-outline--secondary"
|
||||||
size="mini"
|
size="mini"
|
||||||
|
@ -69,10 +79,16 @@
|
||||||
>
|
>
|
||||||
</a-space>
|
</a-space>
|
||||||
<span>
|
<span>
|
||||||
<a-tooltip v-if="!item.isConfig" :content="t('organization.service.unconfiguredTip')" position="br">
|
<a-tooltip v-if="!item.config" :content="t('organization.service.unconfiguredTip')" position="br">
|
||||||
<span><a-switch size="small" :disabled="true" /></span>
|
<span
|
||||||
|
><a-switch
|
||||||
|
v-model="item.enable"
|
||||||
|
size="small"
|
||||||
|
:disabled="true"
|
||||||
|
@change="(v) => changeStatus(v, item.id)"
|
||||||
|
/></span>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<a-switch v-else size="small" />
|
<a-switch v-else v-model="item.enable" size="small" @change="(v) => changeStatus(v, item.id)" />
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -81,163 +97,118 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</MsCard>
|
</MsCard>
|
||||||
<ConfigModal v-model:visible="serviceVisible" :rule="createRules" />
|
<ConfigModal ref="ConfigRef" v-model:visible="serviceVisible" @success="loadList()" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted, reactive } from 'vue';
|
import { ref, onBeforeMount } from 'vue';
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
import MsCard from '@/components/pure/ms-card/index.vue';
|
import MsCard from '@/components/pure/ms-card/index.vue';
|
||||||
|
import { getServiceList, getValidate, resetService, addOrUpdate } from '@/api/modules/setting/serviceIntegration';
|
||||||
import ConfigModal from './conifgModal.vue';
|
import ConfigModal from './conifgModal.vue';
|
||||||
|
import { useUserStore } from '@/store';
|
||||||
|
import useModal from '@/hooks/useModal';
|
||||||
|
import Message from '@arco-design/web-vue/es/message';
|
||||||
|
import { characterLimit } from '@/utils';
|
||||||
|
import type { ServiceList, ServiceItem } from '@/models/setting/serviceIntegration';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
const { openModal } = useModal();
|
||||||
|
|
||||||
const props = defineProps<{
|
const userStore = useUserStore();
|
||||||
|
const lastOrganizationId = userStore.$state?.lastOrganizationId as string;
|
||||||
|
|
||||||
|
defineProps<{
|
||||||
collapseHeight: string;
|
collapseHeight: string;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const keyword = ref('');
|
const keyword = ref('');
|
||||||
const data = ref([
|
const filterList = ref<ServiceList>([]);
|
||||||
{
|
const data = ref<ServiceList>([]);
|
||||||
id: '1-1-1-1',
|
const loading = ref<boolean>(false);
|
||||||
name: 'xxx',
|
|
||||||
enable: true,
|
// 集成列表
|
||||||
isConfig: false,
|
const loadList = async () => {
|
||||||
},
|
loading.value = true;
|
||||||
{
|
try {
|
||||||
id: '2-2-2-2',
|
const result = await getServiceList(lastOrganizationId);
|
||||||
name: 'xxx',
|
data.value = result;
|
||||||
enable: false,
|
filterList.value = result;
|
||||||
isConfig: true,
|
} catch (error) {
|
||||||
},
|
console.log(error);
|
||||||
{
|
} finally {
|
||||||
id: '3-3-3-3',
|
loading.value = false;
|
||||||
name: 'xxx',
|
}
|
||||||
enable: false,
|
};
|
||||||
},
|
|
||||||
{
|
const searchHandler = () => {
|
||||||
id: 'xxxx',
|
filterList.value = data.value.filter((item) => item.title?.includes(keyword.value));
|
||||||
name: 'xxx',
|
};
|
||||||
enable: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'xxxx',
|
|
||||||
name: 'xxx',
|
|
||||||
enable: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '3-3-3-3',
|
|
||||||
name: 'xxx',
|
|
||||||
enable: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '3-3-3-3',
|
|
||||||
name: 'xxx',
|
|
||||||
enable: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'xxxx',
|
|
||||||
name: 'xxx',
|
|
||||||
enable: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'xxxx',
|
|
||||||
name: 'xxx',
|
|
||||||
enable: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '3-3-3-3',
|
|
||||||
name: 'xxx',
|
|
||||||
enable: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '3-3-3-3',
|
|
||||||
name: 'xxx',
|
|
||||||
enable: false,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
const serviceVisible = ref<boolean>(false);
|
const serviceVisible = ref<boolean>(false);
|
||||||
let createRules = reactive([]);
|
const ConfigRef = ref();
|
||||||
|
|
||||||
const editHandler = (item: any) => {
|
// 添加或配置
|
||||||
|
const editHandler = (serviceItem: ServiceItem) => {
|
||||||
serviceVisible.value = true;
|
serviceVisible.value = true;
|
||||||
|
ConfigRef.value.addOrEdit(serviceItem);
|
||||||
|
ConfigRef.value.title = serviceItem.title;
|
||||||
|
};
|
||||||
|
// 重置
|
||||||
|
const resetHandler = async (serviceItem: ServiceItem) => {
|
||||||
|
openModal({
|
||||||
|
type: 'error',
|
||||||
|
title: t('organization.service.resetServiceTip', { name: characterLimit(serviceItem.title) }),
|
||||||
|
content: t('organization.service.resetServiceContentTip'),
|
||||||
|
okText: t('organization.service.confirmReset'),
|
||||||
|
cancelText: t('organization.service.Cancel'),
|
||||||
|
okButtonProps: {
|
||||||
|
status: 'normal',
|
||||||
|
},
|
||||||
|
onBeforeOk: async () => {
|
||||||
|
try {
|
||||||
|
await resetService(serviceItem.id as string);
|
||||||
|
Message.success(t('organization.service.resetConfigTip'));
|
||||||
|
loadList();
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hideCancel: false,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
const resetHandler = (item: any) => {};
|
|
||||||
|
|
||||||
onMounted(() => {
|
// 外部测试连接
|
||||||
setTimeout(() => {
|
const getValidateHandler = async (serviceItem: ServiceItem) => {
|
||||||
const result = JSON.stringify([
|
loading.value = true;
|
||||||
{
|
try {
|
||||||
type: 'input',
|
await getValidate(serviceItem.id as string);
|
||||||
field: 'address',
|
Message.success(t('organization.service.testLinkStatusTip'));
|
||||||
title: 'JIRA地址',
|
loadList();
|
||||||
value: 'JIRA地址',
|
} catch (error) {
|
||||||
validate: [{ type: 'string', required: true, message: 'JIRA地址不能为空' }],
|
console.log(error);
|
||||||
},
|
} finally {
|
||||||
{
|
loading.value = false;
|
||||||
type: 'radio',
|
}
|
||||||
title: '认证方式',
|
};
|
||||||
field: 'method',
|
|
||||||
value: '1',
|
// 切换状态
|
||||||
options: [
|
const changeStatus = async (value: string | number | boolean, id: string | undefined) => {
|
||||||
{
|
loading.value = true;
|
||||||
value: '1',
|
const message = value ? 'organization.service.enableSuccess' : 'organization.service.closeSuccess';
|
||||||
label: 'Auth',
|
try {
|
||||||
},
|
await addOrUpdate({ enable: value as boolean, id }, 'edit');
|
||||||
{
|
Message.success(t(message));
|
||||||
value: '2',
|
loadList();
|
||||||
label: 'Token',
|
} catch (error) {
|
||||||
},
|
console.log(error);
|
||||||
],
|
} finally {
|
||||||
props: {
|
loading.value = false;
|
||||||
type: 'button',
|
}
|
||||||
},
|
};
|
||||||
wrap: {
|
|
||||||
tooltip: 'info提示',
|
onBeforeMount(() => {
|
||||||
},
|
loadList();
|
||||||
control: [
|
|
||||||
{
|
|
||||||
value: '1',
|
|
||||||
rule: [
|
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
field: 'info',
|
|
||||||
title: 'JIRA-账号',
|
|
||||||
value: '账号',
|
|
||||||
validate: [{ type: 'string', required: true, message: 'JIRA账号不能为空' }],
|
|
||||||
wrap: {},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'PassWord',
|
|
||||||
value: '',
|
|
||||||
field: 'password',
|
|
||||||
title: 'JIRA密码',
|
|
||||||
validate: [{ type: 'string', required: true, message: 'JIRA密码不能为空' }],
|
|
||||||
props: {
|
|
||||||
placeholder: '请输入密码',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '2',
|
|
||||||
rule: [
|
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
field: 'token',
|
|
||||||
title: 'Token',
|
|
||||||
value: 'token 账号',
|
|
||||||
validate: [{ type: 'string', required: true, message: 'JIRA账号不能为空' }],
|
|
||||||
wrap: {},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
createRules = JSON.parse(result);
|
|
||||||
}, 1000);
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -245,7 +216,6 @@
|
||||||
.ms-card-wrap {
|
.ms-card-wrap {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
min-width: 1150px;
|
|
||||||
height: calc(100% - 58px) !important;
|
height: calc(100% - 58px) !important;
|
||||||
min-height: 300px;
|
min-height: 300px;
|
||||||
border-radius: var(--border-radius-small);
|
border-radius: var(--border-radius-small);
|
||||||
|
@ -262,7 +232,6 @@
|
||||||
height: 144px;
|
height: 144px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background: white;
|
background: white;
|
||||||
flex-basis: calc(25% - 16px);
|
|
||||||
@apply flex flex-col justify-between;
|
@apply flex flex-col justify-between;
|
||||||
.icon {
|
.icon {
|
||||||
border: 1px solid var(--color-text-n9);
|
border: 1px solid var(--color-text-n9);
|
||||||
|
@ -273,27 +242,20 @@
|
||||||
@apply px-2 py-1 text-xs;
|
@apply px-2 py-1 text-xs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@media screen and (max-width: 992px) {
|
}
|
||||||
.item {
|
@media screen and (min-width: 800px) {
|
||||||
flex-basis: calc(50% - 16px);
|
.item {
|
||||||
}
|
flex-basis: calc(50% - 16px);
|
||||||
}
|
}
|
||||||
@media screen and (min-width: 1000px) and (max-width: 1440px) {
|
}
|
||||||
.item {
|
@media screen and (min-width: 1160px) {
|
||||||
flex-basis: calc(33.3% - 16px);
|
.item {
|
||||||
}
|
flex-basis: calc(33.3% - 16px);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@media screen and (max-width: 1600px) and (min-width: 1800px) {
|
@media screen and (min-width: 1800px) {
|
||||||
.item {
|
.item {
|
||||||
flex-basis: calc(25% - 16px);
|
flex-basis: calc(25% - 16px);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (min-width: 1800px) {
|
|
||||||
.item {
|
|
||||||
flex-basis: calc(25% - 16px);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,17 +4,26 @@
|
||||||
<a-collapse :bordered="false" expand-icon-position="right" @change="changeHandler">
|
<a-collapse :bordered="false" expand-icon-position="right" @change="changeHandler">
|
||||||
<a-collapse-item key="1" class="font-medium" :header="t('organization.service.headerTip')">
|
<a-collapse-item key="1" class="font-medium" :header="t('organization.service.headerTip')">
|
||||||
<template #expand-icon="{ active }">
|
<template #expand-icon="{ active }">
|
||||||
<span v-if="active" class="text-[rgb(var(--primary-6))]">{{ t('organization.service.packUp') }}</span>
|
<span v-if="active" class="float-right -mr-4 text-[rgb(var(--primary-6))]">{{
|
||||||
<span v-else class="text-[rgb(var(--primary-6))]">{{ t('organization.service.expand') }}</span>
|
t('organization.service.packUp')
|
||||||
|
}}</span>
|
||||||
|
<span v-else class="float-right -mr-4 text-[rgb(var(--primary-6))]">{{
|
||||||
|
t('organization.service.expand')
|
||||||
|
}}</span>
|
||||||
</template>
|
</template>
|
||||||
<div class="flex w-[100%] flex-row justify-between text-sm font-normal">
|
<div class="flex w-[100%] flex-row justify-between text-sm font-normal">
|
||||||
<div v-for="(item, index) in cardContent" :key="item.id" class="item" :class="`ms-item-${index}`">
|
<div
|
||||||
<span>
|
v-for="(item, index) in cardContent"
|
||||||
|
:key="item.id"
|
||||||
|
class="item mt-4 p-[16px]"
|
||||||
|
:class="`ms-item-${index}`"
|
||||||
|
>
|
||||||
|
<span class="mr-3">
|
||||||
<svg-icon width="64px" height="46px" :name="item.icon" />
|
<svg-icon width="64px" height="46px" :name="item.icon" />
|
||||||
</span>
|
</span>
|
||||||
<div class="flex h-[100%] flex-1 flex-col justify-between p-4">
|
<div class="flex h-[100%] flex-1 flex-col justify-between">
|
||||||
<div class="flex justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<span class="leading-6">{{ t(item.title) }}</span>
|
<span class="font-normal">{{ t(item.title) }}</span>
|
||||||
<span>
|
<span>
|
||||||
<a-button
|
<a-button
|
||||||
v-for="links of item.skipTitle"
|
v-for="links of item.skipTitle"
|
||||||
|
@ -24,13 +33,14 @@
|
||||||
type="text"
|
type="text"
|
||||||
:href="links.src"
|
:href="links.src"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
|
@click="jumpHandler(links)"
|
||||||
>
|
>
|
||||||
{{ t(links.name) }}
|
{{ t(links.name) }}
|
||||||
</a-button>
|
</a-button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-xs text-[var(--color-text-4)]">
|
<div class="text-xs text-[var(--color-text-4)]">
|
||||||
{{ t(item.description) }}
|
<div class="one-line-text w-[400px]"> {{ t(item.description) }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -47,9 +57,12 @@
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
import MsCard from '@/components/pure/ms-card/index.vue';
|
import MsCard from '@/components/pure/ms-card/index.vue';
|
||||||
import ServiceList from './components/serviceList.vue';
|
import ServiceList from './components/serviceList.vue';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
import type { StepListType, SkipTitle } from '@/models/setting/serviceIntegration';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const cardContent = ref([
|
const router = useRouter();
|
||||||
|
const cardContent = ref<StepListType[]>([
|
||||||
{
|
{
|
||||||
id: '1001',
|
id: '1001',
|
||||||
icon: 'configplugin',
|
icon: 'configplugin',
|
||||||
|
@ -57,11 +70,13 @@
|
||||||
skipTitle: [
|
skipTitle: [
|
||||||
{
|
{
|
||||||
name: 'organization.service.developmentDoc',
|
name: 'organization.service.developmentDoc',
|
||||||
src: '',
|
src: 'https://github.com/metersphere/metersphere-platform-plugin/wiki/%E6%8F%92%E4%BB%B6%E5%BC%80%E5%8F%91%E6%8C%87%E5%8D%97',
|
||||||
|
active: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'organization.service.downPlugin',
|
name: 'organization.service.downPlugin',
|
||||||
src: 'https://github.com/metersphere/metersphere-platform-plugin',
|
src: 'https://github.com/metersphere/metersphere-platform-plugin',
|
||||||
|
active: false,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
step: '@/assets/images/ms_plugindownload.jpg',
|
step: '@/assets/images/ms_plugindownload.jpg',
|
||||||
|
@ -75,6 +90,7 @@
|
||||||
{
|
{
|
||||||
name: 'organization.service.jumpPlugin',
|
name: 'organization.service.jumpPlugin',
|
||||||
src: '',
|
src: '',
|
||||||
|
active: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
step: '@/assets/images/ms_configplugin.jpg',
|
step: '@/assets/images/ms_configplugin.jpg',
|
||||||
|
@ -88,6 +104,13 @@
|
||||||
isCollapse.value = activeKey.length > 0;
|
isCollapse.value = activeKey.length > 0;
|
||||||
collapseHeight.value = activeKey.length > 0 ? '158px' : '72px';
|
collapseHeight.value = activeKey.length > 0 ? '158px' : '72px';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const jumpHandler = (links: SkipTitle) => {
|
||||||
|
if (links.active)
|
||||||
|
router.push({
|
||||||
|
name: 'settingSystemPluginManger',
|
||||||
|
});
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
|
@ -99,9 +122,10 @@
|
||||||
}
|
}
|
||||||
.item {
|
.item {
|
||||||
width: calc(50% - 10px);
|
width: calc(50% - 10px);
|
||||||
|
height: 78px;
|
||||||
border: 1px solid #ffffff;
|
border: 1px solid #ffffff;
|
||||||
box-shadow: 0 0 7px rgb(120 56 135 / 10%);
|
box-shadow: 0 0 7px rgb(120 56 135 / 10%);
|
||||||
@apply flex h-20 items-center rounded-md;
|
@apply flex items-center rounded-md;
|
||||||
}
|
}
|
||||||
.ms-item-0 {
|
.ms-item-0 {
|
||||||
background: url('@/assets/images/ms_plugindownload.jpg') no-repeat center / cover;
|
background: url('@/assets/images/ms_plugindownload.jpg') no-repeat center / cover;
|
||||||
|
|
|
@ -8,15 +8,15 @@ export default {
|
||||||
'organization.service.integrationList': 'Integration of List',
|
'organization.service.integrationList': 'Integration of List',
|
||||||
'organization.service.packUp': 'Pack Up',
|
'organization.service.packUp': 'Pack Up',
|
||||||
'organization.service.expand': 'Expand',
|
'organization.service.expand': 'Expand',
|
||||||
'organization.service.downloadPluginOrDev': 'Download plug-ins or develop plug-ins',
|
'organization.service.downloadPluginOrDev': 'Download & develop',
|
||||||
'organization.service.configPlugin': 'Configuring the plugin',
|
'organization.service.configPlugin': 'Configuring the plugin',
|
||||||
'organization.service.downPlugin': 'Download the plugin',
|
'organization.service.downPlugin': 'Download',
|
||||||
'organization.service.developmentDoc': 'Plug-in development documentation',
|
'organization.service.developmentDoc': 'development documentation',
|
||||||
'organization.service.description':
|
'organization.service.description':
|
||||||
'Download third-party project management platform plug-ins that need to be integrated; you can also develop your own relevant project management platform plug-ins',
|
'Download third-party project management platform plug-ins that need to be integrated; you can also develop your own relevant project management platform plug-ins',
|
||||||
'organization.service.configDescription':
|
'organization.service.configDescription':
|
||||||
'Downloaded or developed plug-ins need to be uploaded to plug-in management, upload, you can configure the current page',
|
'Downloaded or developed plug-ins need to be uploaded to plug-in management, upload, you can configure the current page',
|
||||||
'organization.service.jumpPlugin': 'JUMP to plug-in management',
|
'organization.service.jumpPlugin': 'Jump to plugin',
|
||||||
'organization.service.testLink': 'Test link',
|
'organization.service.testLink': 'Test link',
|
||||||
'organization.service.testLinkStatusTip': 'Test connection successful!',
|
'organization.service.testLinkStatusTip': 'Test connection successful!',
|
||||||
'organization.service.unconfigured': 'Unconfigured',
|
'organization.service.unconfigured': 'Unconfigured',
|
||||||
|
@ -35,21 +35,19 @@ export default {
|
||||||
'organization.service.tableColunmUsergroup': 'UserGroup',
|
'organization.service.tableColunmUsergroup': 'UserGroup',
|
||||||
'organization.service.tableColunmStatus': 'Status',
|
'organization.service.tableColunmStatus': 'Status',
|
||||||
'organization.service.tableColunmActions': 'Actions',
|
'organization.service.tableColunmActions': 'Actions',
|
||||||
'organization.service.service': 'Member',
|
|
||||||
'organization.service.selectMemberScope': 'Select the service you want to add. Multiple selection is supported',
|
|
||||||
'organization.service.selectProjectScope': 'Select the project you want to add. Multiple selection is supported',
|
|
||||||
'organization.service.selectMemberEmptyTip': 'The service can not be empty',
|
|
||||||
'organization.service.selectProjectEmptyTip': 'The project can not be empty',
|
|
||||||
'organization.service.selectUserEmptyTip': 'The user group can not be empty',
|
|
||||||
'organization.service.Confirm': 'Confirm',
|
'organization.service.Confirm': 'Confirm',
|
||||||
'organization.service.Cancel': 'Cancel',
|
'organization.service.Cancel': 'Cancel',
|
||||||
'organization.service.deleteMemberTip': 'Are you sure to remove the user `{name}` ?',
|
'system.user.deleteUserTip': 'Are you sure to delete the user {name} ?',
|
||||||
'system.user.deleteUserTip': 'Are you sure to delete the user `{name}` ?',
|
|
||||||
'organization.service.deleteMemberConfirm': 'Delete',
|
'organization.service.deleteMemberConfirm': 'Delete',
|
||||||
'organization.service.deleteMemberCancel': 'Cancel',
|
|
||||||
'organization.service.deleteMemberSuccess': 'Delete successful',
|
|
||||||
'organization.service.batchModalSuccess': 'Successfully added',
|
|
||||||
'organization.service.batchUpdateSuccess': 'Successfully updated',
|
|
||||||
'organization.service.project': 'Project',
|
'organization.service.project': 'Project',
|
||||||
'organization.service.selectUserScope': 'Please select a user group for the above members',
|
'organization.service.confirmReset': 'Reset',
|
||||||
|
'organization.service.resetServiceTip': 'Confirm reset {name} this service integration?',
|
||||||
|
'organization.service.resetServiceContentTip':
|
||||||
|
'After the Reset, the integration information will be cleared, the project can not integrate with the platform and the platform default template is not available, be careful!',
|
||||||
|
'organization.service.searchService': 'Search by plug-in name',
|
||||||
|
'organization.service.successMessage': 'The test connection was successful',
|
||||||
|
'organization.service.enableSuccess': 'Enable successfully',
|
||||||
|
'organization.service.closeSuccess': 'Disable successfully',
|
||||||
|
'organization.service.configSuccess': 'Configuration successfully',
|
||||||
|
'organization.service.updateSuccess': 'Update successfully',
|
||||||
};
|
};
|
||||||
|
|
|
@ -31,20 +31,18 @@ export default {
|
||||||
'organization.service.tableColunmUsergroup': '用户组',
|
'organization.service.tableColunmUsergroup': '用户组',
|
||||||
'organization.service.tableColunmStatus': '状态',
|
'organization.service.tableColunmStatus': '状态',
|
||||||
'organization.service.tableColunmActions': '操作',
|
'organization.service.tableColunmActions': '操作',
|
||||||
'organization.service.service': '成员',
|
|
||||||
'organization.service.selectMemberScope': '请选择需要添加的成员支持多选',
|
|
||||||
'organization.service.selectProjectScope': '请选择需要添加的项目支持多选',
|
|
||||||
'organization.service.selectMemberEmptyTip': '成员不能为空',
|
|
||||||
'organization.service.selectProjectEmptyTip': '项目不能为空',
|
|
||||||
'organization.service.selectUserEmptyTip': '用户组不能为空',
|
|
||||||
'organization.service.Confirm': '确定',
|
'organization.service.Confirm': '确定',
|
||||||
'organization.service.Cancel': '取消',
|
'organization.service.Cancel': '取消',
|
||||||
'organization.service.deleteMemberTip': '确认移除 `{name}` 这个成员吗?',
|
|
||||||
'organization.service.deleteMemberConfirm': '确认删除',
|
'organization.service.deleteMemberConfirm': '确认删除',
|
||||||
'organization.service.deleteMemberCancel': '取消',
|
|
||||||
'organization.service.deleteMemberSuccess': '删除成功',
|
|
||||||
'organization.service.batchModalSuccess': '添加成功',
|
|
||||||
'organization.service.batchUpdateSuccess': '更新成功',
|
|
||||||
'organization.service.project': '项目',
|
'organization.service.project': '项目',
|
||||||
'organization.service.selectUserScope': '请为以上成员选择用户组',
|
'organization.service.confirmReset': '确认重置',
|
||||||
|
'organization.service.resetServiceTip': '确认重置 {name} 这个服务集成吗?',
|
||||||
|
'organization.service.resetServiceContentTip':
|
||||||
|
'重置后,集成信息将被清空,项目无法与该平台集成且该平台默认模版不可用,谨慎操作!',
|
||||||
|
'organization.service.searchService': '通过插件名称搜索',
|
||||||
|
'organization.service.successMessage': '测试连接成功',
|
||||||
|
'organization.service.enableSuccess': '启用成功',
|
||||||
|
'organization.service.closeSuccess': '禁用成功',
|
||||||
|
'organization.service.configSuccess': '配置成功',
|
||||||
|
'organization.service.updateSuccess': '更新成功',
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,12 +32,22 @@
|
||||||
@expand="handleExpand"
|
@expand="handleExpand"
|
||||||
>
|
>
|
||||||
<template #columns>
|
<template #columns>
|
||||||
<a-table-column :width="300" fixed="left" :title="t('system.plugin.tableColumnsName')" :ellipsis="true">
|
<a-table-column
|
||||||
|
:width="300"
|
||||||
|
fixed="left"
|
||||||
|
:title="t('system.plugin.tableColumnsName')"
|
||||||
|
:ellipsis="true"
|
||||||
|
:tooltip="true"
|
||||||
|
>
|
||||||
<template #cell="{ record }">
|
<template #cell="{ record }">
|
||||||
{{ record.name }} <span class="text-[--color-text-4]">({{ (record.pluginForms || []).length }})</span>
|
{{ record.name }} <span class="text-[--color-text-4]">({{ (record.pluginForms || []).length }})</span>
|
||||||
</template>
|
</template>
|
||||||
</a-table-column>
|
</a-table-column>
|
||||||
<a-table-column :title="t('system.plugin.tableColumnsDescription')" data-index="description" />
|
<a-table-column
|
||||||
|
:title="t('system.plugin.tableColumnsDescription')"
|
||||||
|
data-index="description"
|
||||||
|
:ellipsis="true"
|
||||||
|
/>
|
||||||
<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">
|
||||||
|
|
|
@ -63,6 +63,8 @@
|
||||||
<MsUpload
|
<MsUpload
|
||||||
v-model:file-list="fileList"
|
v-model:file-list="fileList"
|
||||||
accept="jar"
|
accept="jar"
|
||||||
|
:max-size="50"
|
||||||
|
size-unit="MB"
|
||||||
main-text="system.user.importModalDragtext"
|
main-text="system.user.importModalDragtext"
|
||||||
:sub-text="t('system.plugin.supportFormat')"
|
:sub-text="t('system.plugin.supportFormat')"
|
||||||
:show-file-list="false"
|
:show-file-list="false"
|
||||||
|
|
|
@ -22,7 +22,9 @@
|
||||||
<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">{{ t('system.plugin.ServiceIntegration') }}</a-button>
|
<a-button type="outline" @click="router.push({ name: 'settingOrganizationService' })">{{
|
||||||
|
t('system.plugin.ServiceIntegration')
|
||||||
|
}}</a-button>
|
||||||
<a-button type="secondary">{{ t('system.plugin.backPluginList') }}</a-button>
|
<a-button type="secondary">{{ t('system.plugin.backPluginList') }}</a-button>
|
||||||
</a-space>
|
</a-space>
|
||||||
</div>
|
</div>
|
||||||
|
@ -38,8 +40,10 @@
|
||||||
import { useDialog } from '@/hooks/useDialog';
|
import { useDialog } from '@/hooks/useDialog';
|
||||||
import useVisit from '@/hooks/useVisit';
|
import useVisit from '@/hooks/useVisit';
|
||||||
import { useI18n } from '@/hooks/useI18n';
|
import { useI18n } from '@/hooks/useI18n';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
const router = useRouter();
|
||||||
const visitedKey = 'doNotShowAgain';
|
const visitedKey = 'doNotShowAgain';
|
||||||
const { addVisited } = useVisit(visitedKey);
|
const { addVisited } = useVisit(visitedKey);
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
|
|
Loading…
Reference in New Issue