feat(系统设置): 新增系统参数配置扫码登陆平台页面
This commit is contained in:
parent
a4d9799a0f
commit
e7304e5272
|
@ -85,6 +85,8 @@ public class PermissionConstants {
|
|||
public static final String SYSTEM_PARAMETER_SETTING_AUTH_READ_DELETE = "SYSTEM_PARAMETER_SETTING_AUTH:READ+DELETE";
|
||||
public static final String SYSTEM_PARAMETER_SETTING_DISPLAY_READ = "SYSTEM_PARAMETER_SETTING_DISPLAY:READ";
|
||||
public static final String SYSTEM_PARAMETER_SETTING_DISPLAY_READ_UPDATE = "SYSTEM_PARAMETER_SETTING_DISPLAY:READ+UPDATE";
|
||||
public static final String SYSTEM_PARAMETER_SETTING_QRCODE_READ = "SYSTEM_PARAMETER_SETTING_QRCODE:READ";
|
||||
public static final String SYSTEM_PARAMETER_SETTING_QRCODE_UPDATE = "SYSTEM_PARAMETER_SETTING_QRCODE:READ+UPDATE";
|
||||
public static final String SYSTEM_PARAMETER_SETTING_MEMORY_CLEAN_READ = "SYSTEM_PARAMETER_SETTING_MEMORY_CLEAN:READ";
|
||||
public static final String SYSTEM_PARAMETER_SETTING_MEMORY_CLEAN_READ_UPDATE = "SYSTEM_PARAMETER_SETTING_MEMORY_CLEAN:READ+UPDATE";
|
||||
|
||||
|
|
|
@ -245,6 +245,8 @@ permission.system_parameter_setting_auth.read=认证设置-查询
|
|||
permission.system_parameter_setting_auth.add=认证设置-创建
|
||||
permission.system_parameter_setting_auth.update=认证设置-编辑
|
||||
permission.system_parameter_setting_auth.delete=认证设置-删除
|
||||
permission.system_parameter_setting_qrcode.read=扫码登录-查询
|
||||
permission.system_parameter_setting_qrcode.update=扫码登录-编辑
|
||||
permission.organization_user_role.name=用户组
|
||||
permission.organization_member.name=成员
|
||||
permission.service_integration.name=服务集成
|
||||
|
|
|
@ -248,6 +248,8 @@ permission.system_parameter_setting_auth.update=Auth parameter setting update
|
|||
permission.system_parameter_setting_auth.delete=Auth parameter setting delete
|
||||
permission.system_parameter_setting_memory_clean.read=Memory clean parameter setting read
|
||||
permission.system_parameter_setting_memory_clean.update=Memory clean parameter setting update
|
||||
permission.system_parameter_setting_qrcode.read=Scan the QR code to log in-query
|
||||
permission.system_parameter_setting_qrcode.update=Scan the QR code to log in-Edit
|
||||
permission.organization_user_role.name=User group
|
||||
permission.organization_member.name=User
|
||||
permission.service_integration.name=Service Integration
|
||||
|
|
|
@ -249,6 +249,8 @@ permission.system_parameter_setting_auth.update=认证设置-编辑
|
|||
permission.system_parameter_setting_auth.delete=认证设置-删除
|
||||
permission.system_parameter_setting_memory_clean.read=内存清理-查询
|
||||
permission.system_parameter_setting_memory_clean.update=内存清理-编辑
|
||||
permission.system_parameter_setting_qrcode.read=扫码登录-查询
|
||||
permission.system_parameter_setting_qrcode.update=扫码登录-编辑
|
||||
permission.organization_user_role.name=用户组
|
||||
permission.organization_member.name=成员
|
||||
permission.service_integration.name=服务集成
|
||||
|
|
|
@ -248,6 +248,8 @@ permission.system_parameter_setting_auth.update=認證設置-編輯
|
|||
permission.system_parameter_setting_auth.delete=認證設置-刪除
|
||||
permission.system_parameter_setting_memory_clean.read=內存清理-查詢
|
||||
permission.system_parameter_setting_memory_clean.update=內存清理-編輯
|
||||
permission.system_parameter_setting_qrcode.read=掃碼登入-查詢
|
||||
permission.system_parameter_setting_qrcode.update=掃碼登入-編輯
|
||||
permission.organization_user_role.name=用戶組
|
||||
permission.organization_member.name=成員
|
||||
permission.service_integration.name=服務集成
|
||||
|
|
|
@ -162,6 +162,16 @@
|
|||
{
|
||||
"id": "SYSTEM_PARAMETER_SETTING_MEMORY_CLEAN:READ+UPDATE",
|
||||
"name": "permission.system_parameter_setting_memory_clean.update"
|
||||
},
|
||||
{
|
||||
"id": "SYSTEM_PARAMETER_SETTING_QRCODE:READ",
|
||||
"name": "permission.system_parameter_setting_qrcode.read",
|
||||
"license": true
|
||||
},
|
||||
{
|
||||
"id": "SYSTEM_PARAMETER_SETTING_QRCODE:READ",
|
||||
"name": "permission.system_parameter_setting_qrcode.update",
|
||||
"license": true
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
import MSR from '@/api/http/index';
|
||||
import {
|
||||
GetDingTalkInfoUrl,
|
||||
GetPlatformInfoUrl,
|
||||
GetWeComInfoUrl,
|
||||
PostDingTalkEnableUrl,
|
||||
PostDingTalkSaveUrl,
|
||||
PostValidateDingTalkUrl,
|
||||
PostValidateWeComUrl,
|
||||
PostWeComEnableUrl,
|
||||
PostWeComSaveUrl,
|
||||
} from '@/api/requrls/setting/qrCode';
|
||||
|
||||
import { DingTalkInfo, EnableEditorRequest, PlatformSourceList, WeComInfo } from '@/models/setting/qrCode';
|
||||
|
||||
// 获取企业微信配置
|
||||
export function getWeComInfo() {
|
||||
return MSR.get<WeComInfo>({ url: GetWeComInfoUrl });
|
||||
}
|
||||
|
||||
// 获取钉钉配置
|
||||
export function getDingInfo() {
|
||||
return MSR.get<DingTalkInfo>({ url: GetDingTalkInfoUrl });
|
||||
}
|
||||
|
||||
// 保存企业微信登陆配置
|
||||
export function saveWeComConfig(data: WeComInfo) {
|
||||
return MSR.post({ url: PostWeComSaveUrl, data });
|
||||
}
|
||||
|
||||
// 保存钉钉登陆配置
|
||||
export function saveDingTalkConfig(data: DingTalkInfo) {
|
||||
return MSR.post({ url: PostDingTalkSaveUrl, data });
|
||||
}
|
||||
|
||||
// 校验企业微信外链接
|
||||
export function validateWeComConfig(data: WeComInfo) {
|
||||
return MSR.post({ url: PostValidateWeComUrl, data });
|
||||
}
|
||||
|
||||
// 校验钉钉外链接
|
||||
export function validateDingTalkConfig(data: DingTalkInfo) {
|
||||
return MSR.post({ url: PostValidateDingTalkUrl, data });
|
||||
}
|
||||
|
||||
// 开启企业微信登陆
|
||||
export function enableWeCom(data: EnableEditorRequest) {
|
||||
return MSR.post({ url: PostWeComEnableUrl, data });
|
||||
}
|
||||
|
||||
// 开启钉钉登陆
|
||||
export function enableDingTalk(data: EnableEditorRequest) {
|
||||
return MSR.post({ url: PostDingTalkEnableUrl, data });
|
||||
}
|
||||
|
||||
// 获取所有平台配置基础信息
|
||||
export function getPlatformSourceList() {
|
||||
return MSR.get<PlatformSourceList>({ url: GetPlatformInfoUrl });
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
export const PostValidateWeComUrl = '/we_com/validate';
|
||||
export const GetWeComInfoUrl = '/we_com/info/with_detail';
|
||||
export const PostWeComSaveUrl = '/we_com/save';
|
||||
export const PostWeComEnableUrl = '/we_com/enable';
|
||||
export const PostValidateDingTalkUrl = '/ding_talk/validate';
|
||||
export const GetDingTalkInfoUrl = '/ding_talk/info/with_detail';
|
||||
export const PostDingTalkSaveUrl = '/ding_talk/save';
|
||||
export const PostDingTalkEnableUrl = '/ding_talk/enable';
|
||||
export const GetPlatformInfoUrl = '/setting/get/platform/info';
|
|
@ -0,0 +1,40 @@
|
|||
export interface DingTalkInfo {
|
||||
agentId: string;
|
||||
appKey: string;
|
||||
appSecret: string;
|
||||
callBack: string;
|
||||
enable: boolean;
|
||||
valid: boolean;
|
||||
}
|
||||
|
||||
export interface WeComInfo {
|
||||
corpId: string;
|
||||
agentId: string;
|
||||
appSecret: string;
|
||||
callBack: string;
|
||||
enable: boolean;
|
||||
valid: boolean;
|
||||
}
|
||||
|
||||
export interface EnableEditorRequest {
|
||||
enable: boolean;
|
||||
}
|
||||
|
||||
export interface PlatformSource {
|
||||
platform: string;
|
||||
enable: boolean;
|
||||
valid: boolean;
|
||||
}
|
||||
|
||||
export interface PlatformConfigItem {
|
||||
key: string;
|
||||
title: string;
|
||||
description: string;
|
||||
enable: boolean;
|
||||
valid: boolean;
|
||||
logo: string;
|
||||
edit: boolean;
|
||||
}
|
||||
|
||||
export type PlatformSourceList = PlatformSource[];
|
||||
export type PlatformConfigList = PlatformConfigItem[];
|
|
@ -0,0 +1,196 @@
|
|||
<template>
|
||||
<a-modal
|
||||
v-model:visible="detailVisible"
|
||||
title-align="start"
|
||||
class="ms-modal-upload ms-modal-medium"
|
||||
:width="680"
|
||||
:loading="loading"
|
||||
>
|
||||
<template #title>
|
||||
{{ t('project.messageManagement.DING_TALK') }}
|
||||
</template>
|
||||
|
||||
<a-form class="ms-form rounded-[4px]" :model="dingTalkForm" layout="vertical">
|
||||
<a-form-item
|
||||
field="appKey"
|
||||
:label="t('system.config.qrCodeConfig.appKey')"
|
||||
:rules="[{ required: true, message: t('system.config.qrCodeConfig.appKey.required') }]"
|
||||
:validate-trigger="['blur', 'input']"
|
||||
asterisk-position="end"
|
||||
>
|
||||
<a-input v-model="dingTalkForm.appKey" :max-length="255" :placeholder="t('formCreate.PleaseEnter')" />
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
field="agentId"
|
||||
:label="t('system.config.qrCodeConfig.agentId')"
|
||||
:rules="[{ required: true, message: t('system.config.qrCodeConfig.agentId.required') }]"
|
||||
:validate-trigger="['blur', 'input']"
|
||||
asterisk-position="end"
|
||||
>
|
||||
<a-input v-model="dingTalkForm.agentId" :max-length="255" :placeholder="t('formCreate.PleaseEnter')" />
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
field="appSecret"
|
||||
:label="t('system.config.qrCodeConfig.appSecret')"
|
||||
:rules="[{ required: true, message: t('system.config.qrCodeConfig.appSecret.required') }]"
|
||||
:validate-trigger="['blur', 'input']"
|
||||
asterisk-position="end"
|
||||
>
|
||||
<a-input-password
|
||||
v-model="dingTalkForm.appSecret"
|
||||
allow-clear
|
||||
:max-length="255"
|
||||
:placeholder="t('formCreate.PleaseEnter')"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
field="callBack"
|
||||
:label="t('system.config.qrCodeConfig.callBack')"
|
||||
:rules="[{ required: true, message: t('system.config.qrCodeConfig.callBack.required') }]"
|
||||
:validate-trigger="['blur', 'input']"
|
||||
asterisk-position="end"
|
||||
>
|
||||
<a-input v-model="dingTalkForm.callBack" :max-length="255" :placeholder="t('formCreate.PleaseEnter')" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<template #footer>
|
||||
<div class="footer-button">
|
||||
<div class="ms-switch">
|
||||
<a-switch
|
||||
v-model="dingTalkForm.enable"
|
||||
class="ms-form-table-input-switch execute-form-table-input-switch"
|
||||
size="small"
|
||||
/>
|
||||
<span class="ml-3 font-normal text-[var(--color-text-1)]">{{ t('system.config.qrCodeConfig.enable') }}</span>
|
||||
</div>
|
||||
<div class="ms-button-group">
|
||||
<a-button type="secondary" class="ml-[14px]" @click="cancelEdit">
|
||||
{{ t('common.cancel') }}
|
||||
</a-button>
|
||||
<a-button
|
||||
type="outline"
|
||||
class="ml-[14px]"
|
||||
:disabled="
|
||||
dingTalkForm.appKey == '' &&
|
||||
dingTalkForm.appSecret == '' &&
|
||||
dingTalkForm.agentId == '' &&
|
||||
dingTalkForm.callBack == ''
|
||||
"
|
||||
@click="validateInfo"
|
||||
>
|
||||
{{ t('organization.service.testLink') }}
|
||||
</a-button>
|
||||
<a-button type="primary" class="ml-[14px]" @click="saveInfo">
|
||||
{{ t('common.confirm') }}
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
|
||||
import { getDingInfo, saveDingTalkConfig, validateDingTalkConfig } from '@/api/modules/setting/qrCode';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
|
||||
import { DingTalkInfo } from '@/models/setting/qrCode';
|
||||
|
||||
import Message from '@arco-design/web-vue/es/message';
|
||||
|
||||
const { t } = useI18n();
|
||||
const dingTalkForm = ref<DingTalkInfo>({
|
||||
agentId: '',
|
||||
appKey: '',
|
||||
appSecret: '',
|
||||
callBack: '',
|
||||
enable: false,
|
||||
valid: false,
|
||||
});
|
||||
|
||||
const loading = ref<boolean>(false);
|
||||
const detailVisible = ref<boolean>(false);
|
||||
const props = defineProps<{
|
||||
visible: boolean;
|
||||
}>();
|
||||
|
||||
const emits = defineEmits<{
|
||||
(event: 'update:visible', visible: boolean): void;
|
||||
(event: 'success'): void;
|
||||
}>();
|
||||
|
||||
// 集成列表
|
||||
const loadList = async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
dingTalkForm.value = await getDingInfo();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
watchEffect(() => {
|
||||
detailVisible.value = props.visible;
|
||||
});
|
||||
watch(
|
||||
() => detailVisible.value,
|
||||
(val) => {
|
||||
emits('update:visible', val);
|
||||
loadList();
|
||||
}
|
||||
);
|
||||
|
||||
function cancelEdit() {
|
||||
detailVisible.value = false;
|
||||
emits('update:visible', detailVisible.value);
|
||||
}
|
||||
|
||||
async function validateInfo() {
|
||||
loading.value = true;
|
||||
try {
|
||||
await validateDingTalkConfig(dingTalkForm.value);
|
||||
Message.success(t('organization.service.testLinkStatusTip'));
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function saveInfo() {
|
||||
loading.value = true;
|
||||
try {
|
||||
await saveDingTalkConfig(dingTalkForm.value);
|
||||
Message.success(t('organization.service.testLinkStatusTip'));
|
||||
emits('success');
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
detailVisible.value = false;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.footer-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.ms-switch {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
}
|
||||
.ms-button-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,311 @@
|
|||
<template>
|
||||
<MsCard simple class="mb-[16px]" auto-height :loading="loading">
|
||||
<div class="outer-wrapper">
|
||||
<div class="mb-[16px] flex justify-between">
|
||||
<div class="font-medium text-[var(--color-text-000)]">{{ t('organization.service.integrationList') }}</div>
|
||||
</div>
|
||||
<div class="ms-card-wrap">
|
||||
<a-scrollbar
|
||||
:style="{
|
||||
overflow: 'auto',
|
||||
height: `calc(100vh - 196px)`,
|
||||
}"
|
||||
>
|
||||
<div v-if="filterList.length" class="list">
|
||||
<div v-for="item of filterList" :key="item.key" class="item">
|
||||
<div class="flex">
|
||||
<span class="float-left mr-2 h-[40px] w-[40px] rounded">
|
||||
<MsIcon :type="item.logo" size="40"></MsIcon>
|
||||
</span>
|
||||
<div class="flex flex-col justify-start">
|
||||
<p>
|
||||
<span class="mr-4 font-semibold">{{ item.title }}</span>
|
||||
<span v-if="!item.valid" class="ms-enable">{{ t('organization.service.unconfigured') }}</span>
|
||||
<span
|
||||
v-else
|
||||
class="ms-enable active"
|
||||
:style="{
|
||||
background: 'rgb(var(--success-1))',
|
||||
color: 'rgb(var(--success-6))',
|
||||
}"
|
||||
>{{ t('organization.service.configured') }}</span
|
||||
>
|
||||
</p>
|
||||
<p class="mt-2 text-sm text-[var(--color-text-4)]">{{ item.description }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<a-space>
|
||||
<a-tooltip v-if="!item.valid" :content="t('organization.service.unconfiguredTip')" position="tl">
|
||||
<span>
|
||||
<a-button
|
||||
v-if="!item.valid"
|
||||
type="outline"
|
||||
class="arco-btn-outline--secondary"
|
||||
size="mini"
|
||||
:disabled="!item.valid || !hasAnyPermission(['SYSTEM_SERVICE_INTEGRATION:READ+UPDATE'])"
|
||||
@click="getValidateHandler(item.key)"
|
||||
>{{ t('organization.service.testLink') }}</a-button
|
||||
></span
|
||||
>
|
||||
</a-tooltip>
|
||||
<a-button
|
||||
v-else
|
||||
:disabled="!item.valid || !hasAnyPermission(['SYSTEM_SERVICE_INTEGRATION:READ+UPDATE'])"
|
||||
type="outline"
|
||||
class="arco-btn-outline--secondary"
|
||||
size="mini"
|
||||
@click="getValidateHandler(item.key)"
|
||||
>{{ t('organization.service.testLink') }}
|
||||
</a-button>
|
||||
<a-button
|
||||
v-if="item.edit"
|
||||
v-permission="['SYSTEM_SERVICE_INTEGRATION:READ+UPDATE']"
|
||||
type="outline"
|
||||
class="arco-btn-outline--secondary"
|
||||
size="mini"
|
||||
@click="editHandler(item.key)"
|
||||
>{{ t('organization.service.edit') }}
|
||||
</a-button>
|
||||
<a-button
|
||||
v-else
|
||||
v-permission="['SYSTEM_SERVICE_INTEGRATION:READ+ADD']"
|
||||
type="outline"
|
||||
class="arco-btn-outline--secondary"
|
||||
size="mini"
|
||||
@click="editHandler(item.key)"
|
||||
>{{ t('common.add') }}
|
||||
</a-button>
|
||||
</a-space>
|
||||
<span>
|
||||
<a-tooltip v-if="!item.valid" :content="t('organization.service.unconfiguredTip')" position="br">
|
||||
<span
|
||||
><a-switch
|
||||
v-model="item.enable"
|
||||
size="small"
|
||||
:disabled="true"
|
||||
@change="(v) => changeStatus(v, item.key)"
|
||||
/></span>
|
||||
</a-tooltip>
|
||||
<a-switch
|
||||
v-else
|
||||
v-model="item.enable"
|
||||
size="small"
|
||||
:disabled="!hasAnyPermission(['SYSTEM_SERVICE_INTEGRATION:READ+UPDATE'])"
|
||||
@change="(v) => changeStatus(v, item.key)"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a-empty v-if="!filterList.length" class="mt-20"></a-empty>
|
||||
</a-scrollbar>
|
||||
</div>
|
||||
</div>
|
||||
</MsCard>
|
||||
<we-com-modal v-model:visible="showWeComModal" @success="loadList()" />
|
||||
<ding-talk-modal v-model:visible="showDingTalkModal" @success="loadList()" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onBeforeMount, ref } from 'vue';
|
||||
|
||||
import MsCard from '@/components/pure/ms-card/index.vue';
|
||||
import MsIcon from '@/components/pure/ms-icon-font/index.vue';
|
||||
import DingTalkModal from '@/views/setting/system/config/components/dingTalkModal.vue';
|
||||
import WeComModal from '@/views/setting/system/config/components/weComModal.vue';
|
||||
|
||||
import {
|
||||
enableDingTalk,
|
||||
enableWeCom,
|
||||
getPlatformSourceList,
|
||||
validateDingTalkConfig,
|
||||
validateWeComConfig,
|
||||
} from '@/api/modules/setting/qrCode';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { hasAnyPermission } from '@/utils/permission';
|
||||
|
||||
import {
|
||||
DingTalkInfo,
|
||||
EnableEditorRequest,
|
||||
PlatformConfigItem,
|
||||
PlatformConfigList,
|
||||
PlatformSource,
|
||||
PlatformSourceList,
|
||||
WeComInfo,
|
||||
} from '@/models/setting/qrCode';
|
||||
|
||||
import Message from '@arco-design/web-vue/es/message';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const filterList = ref<PlatformConfigList>([
|
||||
{
|
||||
key: 'WE_COM',
|
||||
title: t('project.messageManagement.WE_COM'),
|
||||
description: '为企业打造的专业办公管理工具',
|
||||
enable: false,
|
||||
valid: false,
|
||||
logo: 'icon-logo_wechat-work',
|
||||
edit: false,
|
||||
},
|
||||
{
|
||||
key: 'DING_TALK',
|
||||
title: t('project.messageManagement.DING_TALK'),
|
||||
description: '企业级智能移动办公平台',
|
||||
enable: false,
|
||||
valid: false,
|
||||
logo: 'icon-logo_dingtalk',
|
||||
edit: false,
|
||||
},
|
||||
]);
|
||||
const data = ref<PlatformSourceList>([]);
|
||||
const loading = ref<boolean>(false);
|
||||
const showWeComModal = ref<boolean>(false);
|
||||
const showDingTalkModal = ref<boolean>(false);
|
||||
|
||||
const weComInfo = ref<WeComInfo>({
|
||||
corpId: '',
|
||||
agentId: '',
|
||||
appSecret: '',
|
||||
callBack: '',
|
||||
enable: false,
|
||||
valid: false,
|
||||
});
|
||||
|
||||
const dingTalkInfo = ref<DingTalkInfo>({
|
||||
agentId: '',
|
||||
appKey: '',
|
||||
appSecret: '',
|
||||
callBack: '',
|
||||
enable: false,
|
||||
valid: false,
|
||||
});
|
||||
|
||||
// 集成列表
|
||||
const loadList = async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
data.value = await getPlatformSourceList();
|
||||
filterList.value.forEach((filterKey: PlatformConfigItem) => {
|
||||
data.value.forEach((dataKey: PlatformSource) => {
|
||||
if (filterKey.key === dataKey.platform) {
|
||||
filterKey.enable = dataKey.enable;
|
||||
filterKey.valid = dataKey.valid;
|
||||
filterKey.edit = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 添加或配置
|
||||
const editHandler = (key: string) => {
|
||||
if (key === 'WE_COM') {
|
||||
showWeComModal.value = true;
|
||||
showDingTalkModal.value = false;
|
||||
} else if (key === 'DING_TALK') {
|
||||
showWeComModal.value = false;
|
||||
showDingTalkModal.value = true;
|
||||
}
|
||||
};
|
||||
|
||||
// 外部测试连接
|
||||
const getValidateHandler = async (key: string) => {
|
||||
loading.value = true;
|
||||
try {
|
||||
if (key === 'WE_COM') {
|
||||
await validateWeComConfig(weComInfo.value);
|
||||
} else if (key === 'DING_TALK') {
|
||||
await validateDingTalkConfig(dingTalkInfo.value);
|
||||
}
|
||||
Message.success(t('organization.service.testLinkStatusTip'));
|
||||
loadList();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 切换状态
|
||||
const changeStatus = async (value: string | number | boolean, key: string | undefined) => {
|
||||
loading.value = true;
|
||||
const message = value ? 'organization.service.enableSuccess' : 'organization.service.closeSuccess';
|
||||
const params: EnableEditorRequest = {
|
||||
enable: typeof value === 'boolean' ? value : false,
|
||||
};
|
||||
try {
|
||||
if (key === 'WE_COM') {
|
||||
await enableWeCom(params);
|
||||
} else if (key === 'DING_TALK') {
|
||||
await enableDingTalk(params);
|
||||
}
|
||||
Message.success(t(message));
|
||||
loadList();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
onBeforeMount(() => {
|
||||
loadList();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.ms-card-wrap {
|
||||
overflow: hidden;
|
||||
padding: 8px;
|
||||
height: calc(100% - 58px) !important;
|
||||
min-height: 300px;
|
||||
border-radius: var(--border-radius-small);
|
||||
background: var(--color-text-n9);
|
||||
|
||||
.list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
align-content: flex-start;
|
||||
width: 100%;
|
||||
|
||||
.item {
|
||||
margin: 8px;
|
||||
padding: 24px;
|
||||
height: 144px;
|
||||
border-radius: 4px;
|
||||
background: white;
|
||||
@apply flex flex-col justify-between;
|
||||
|
||||
.ms-enable {
|
||||
font-size: 12px;
|
||||
border-radius: var(--border-radius-small);
|
||||
background: var(--color-text-n9);
|
||||
@apply px-2 py-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 800px) {
|
||||
.item {
|
||||
flex-basis: calc(50% - 16px);
|
||||
}
|
||||
}
|
||||
@media screen and (min-width: 1160px) {
|
||||
.item {
|
||||
flex-basis: calc(33.3% - 16px);
|
||||
}
|
||||
}
|
||||
@media screen and (min-width: 1800px) {
|
||||
.item {
|
||||
flex-basis: calc(25% - 16px);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,193 @@
|
|||
<template>
|
||||
<a-modal
|
||||
v-model:visible="detailVisible"
|
||||
title-align="start"
|
||||
class="ms-modal-upload ms-modal-medium"
|
||||
:width="680"
|
||||
:loading="loading"
|
||||
>
|
||||
<template #title>
|
||||
{{ t('project.messageManagement.WE_COM') }}
|
||||
</template>
|
||||
|
||||
<a-form class="ms-form rounded-[4px]" :model="weComForm" layout="vertical">
|
||||
<a-form-item
|
||||
field="corpId"
|
||||
:label="t('system.config.qrCodeConfig.corpId')"
|
||||
:rules="[{ required: true, message: t('system.config.qrCodeConfig.corpId.required') }]"
|
||||
:validate-trigger="['blur', 'input']"
|
||||
asterisk-position="end"
|
||||
>
|
||||
<a-input v-model="weComForm.corpId" :max-length="255" :placeholder="t('formCreate.PleaseEnter')" />
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
field="agentId"
|
||||
:label="t('system.config.qrCodeConfig.agentId')"
|
||||
:rules="[{ required: true, message: t('system.config.qrCodeConfig.agentId.required') }]"
|
||||
:validate-trigger="['blur', 'input']"
|
||||
asterisk-position="end"
|
||||
>
|
||||
<a-input v-model="weComForm.agentId" :max-length="255" :placeholder="t('formCreate.PleaseEnter')" />
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
field="appSecret"
|
||||
:label="t('system.config.qrCodeConfig.appSecret')"
|
||||
:rules="[{ required: true, message: t('system.config.qrCodeConfig.appSecret.required') }]"
|
||||
:validate-trigger="['blur', 'input']"
|
||||
asterisk-position="end"
|
||||
>
|
||||
<a-input-password
|
||||
v-model="weComForm.appSecret"
|
||||
allow-clear
|
||||
:max-length="255"
|
||||
:placeholder="t('formCreate.PleaseEnter')"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
field="callBack"
|
||||
:label="t('system.config.qrCodeConfig.callBack')"
|
||||
:rules="[{ required: true, message: t('system.config.qrCodeConfig.callBack.required') }]"
|
||||
:validate-trigger="['blur', 'input']"
|
||||
asterisk-position="end"
|
||||
>
|
||||
<a-input v-model="weComForm.callBack" :max-length="255" :placeholder="t('formCreate.PleaseEnter')" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<template #footer>
|
||||
<div class="footer-button">
|
||||
<div class="ms-switch">
|
||||
<a-switch
|
||||
v-model="weComForm.enable"
|
||||
class="ms-form-table-input-switch execute-form-table-input-switch"
|
||||
size="small"
|
||||
/>
|
||||
<span class="ml-3 font-normal text-[var(--color-text-1)]">{{ t('system.config.qrCodeConfig.enable') }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<a-button class="ml-[14px]" type="secondary" @click="cancelEdit">
|
||||
{{ t('common.cancel') }}
|
||||
</a-button>
|
||||
<a-button
|
||||
class="ml-[14px]"
|
||||
type="outline"
|
||||
:disabled="
|
||||
weComForm.corpId == '' && weComForm.appSecret == '' && weComForm.agentId == '' && weComForm.callBack == ''
|
||||
"
|
||||
@click="validateInfo"
|
||||
>
|
||||
{{ t('organization.service.testLink') }}
|
||||
</a-button>
|
||||
<a-button class="ml-[14px]" type="primary" @click="saveInfo">
|
||||
{{ t('common.confirm') }}
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
|
||||
import { getWeComInfo, saveWeComConfig, validateWeComConfig } from '@/api/modules/setting/qrCode';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
|
||||
import { WeComInfo } from '@/models/setting/qrCode';
|
||||
|
||||
import Message from '@arco-design/web-vue/es/message';
|
||||
|
||||
const { t } = useI18n();
|
||||
const weComForm = ref<WeComInfo>({
|
||||
corpId: '',
|
||||
agentId: '',
|
||||
appSecret: '',
|
||||
callBack: '',
|
||||
enable: false,
|
||||
valid: false,
|
||||
});
|
||||
|
||||
const emits = defineEmits<{
|
||||
(event: 'update:visible', visible: boolean): void;
|
||||
(event: 'success'): void;
|
||||
}>();
|
||||
|
||||
const loading = ref<boolean>(false);
|
||||
const detailVisible = ref<boolean>(false);
|
||||
const props = defineProps<{
|
||||
visible: boolean;
|
||||
}>();
|
||||
|
||||
// 集成列表
|
||||
const loadList = async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
weComForm.value = await getWeComInfo();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
watchEffect(() => {
|
||||
detailVisible.value = props.visible;
|
||||
});
|
||||
watch(
|
||||
() => detailVisible.value,
|
||||
(val) => {
|
||||
emits('update:visible', val);
|
||||
loadList();
|
||||
}
|
||||
);
|
||||
|
||||
function cancelEdit() {
|
||||
detailVisible.value = false;
|
||||
emits('update:visible', detailVisible.value);
|
||||
}
|
||||
|
||||
async function validateInfo() {
|
||||
loading.value = true;
|
||||
try {
|
||||
await validateWeComConfig(weComForm.value);
|
||||
Message.success(t('organization.service.testLinkStatusTip'));
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function saveInfo() {
|
||||
loading.value = true;
|
||||
try {
|
||||
await saveWeComConfig(weComForm.value);
|
||||
Message.success(t('organization.service.testLinkStatusTip'));
|
||||
emits('success');
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
detailVisible.value = false;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.footer-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.ms-switch {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
}
|
||||
.ms-button-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
}
|
||||
</style>
|
|
@ -1,6 +1,7 @@
|
|||
<template>
|
||||
<MsTabCard v-model:active-tab="activeTab" :title="t('system.config.parameterConfig')" :tab-list="tabList" />
|
||||
<baseConfig v-if="activeTab === 'baseConfig'" v-show="activeTab === 'baseConfig'" />
|
||||
<qrCodeConfig v-if="activeTab === 'qrCodeConfig'" v-show="activeTab === 'qrCodeConfig'" />
|
||||
<pageConfig v-if="isInitPageConfig" v-show="activeTab === 'pageConfig'" />
|
||||
<authConfig v-if="isInitAuthConfig" v-show="activeTab === 'authConfig'" />
|
||||
<memoryCleanup v-if="isInitMemoryCleanup" v-show="activeTab === 'memoryCleanup'" />
|
||||
|
@ -21,6 +22,7 @@
|
|||
// 异步组件加载
|
||||
const baseConfig = defineAsyncComponent(() => import('./components/baseConfig.vue'));
|
||||
const pageConfig = defineAsyncComponent(() => import('./components/pageConfig.vue'));
|
||||
const qrCodeConfig = defineAsyncComponent(() => import('./components/qrCodeConfig.vue'));
|
||||
const authConfig = defineAsyncComponent(() => import('./components/authConfig.vue'));
|
||||
const memoryCleanup = defineAsyncComponent(() => import('./components/memoryCleanup.vue'));
|
||||
|
||||
|
@ -31,9 +33,15 @@
|
|||
const isInitPageConfig = ref(activeTab.value === 'pageConfig');
|
||||
const isInitAuthConfig = ref(activeTab.value === 'authConfig');
|
||||
const isInitMemoryCleanup = ref(activeTab.value === 'memoryCleanup');
|
||||
const isInitQrCodeConfig = ref(activeTab.value === 'qrCodeConfig');
|
||||
const tabList = ref([
|
||||
{ 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: 'qrCodeConfig',
|
||||
title: t('system.config.qrCodeConfig'),
|
||||
permission: ['SYSTEM_PARAMETER_SETTING_DISPLAY:READ'],
|
||||
},
|
||||
{ key: 'authConfig', title: t('system.config.authConfig'), permission: ['SYSTEM_PARAMETER_SETTING_AUTH:READ'] },
|
||||
{
|
||||
key: 'memoryCleanup',
|
||||
|
@ -51,6 +59,8 @@
|
|||
isInitAuthConfig.value = true;
|
||||
} else if (val === 'memoryCleanup' && !isInitMemoryCleanup.value) {
|
||||
isInitMemoryCleanup.value = true;
|
||||
} else if (val === 'qrCodeConfig' && !isInitMemoryCleanup.value) {
|
||||
isInitQrCodeConfig.value = true;
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
@ -2,6 +2,7 @@ export default {
|
|||
'system.config.parameterConfig': 'System Parameters Configuration',
|
||||
'system.config.baseConfig': 'Basic Settings',
|
||||
'system.config.pageConfig': 'Interface settings',
|
||||
'system.config.qrCodeConfig': 'Scan the QR code to log in',
|
||||
'system.config.authConfig': 'Authentication Settings',
|
||||
'system.config.baseInfo': 'Base Information',
|
||||
'system.config.update': 'Update',
|
||||
|
@ -206,4 +207,16 @@ export default {
|
|||
'Effective for all projects in the system, the system will clear unset change history in the early morning',
|
||||
'system.config.memoryCleanup.numberTip':
|
||||
'The system defaults to a maximum of 100,000 records, and will keep all records if exceeded',
|
||||
'system.config.qrCodeConfig.corpId': 'Corp Id',
|
||||
'system.config.qrCodeConfig.agentId': 'Agent Id',
|
||||
'system.config.qrCodeConfig.appKey': 'App Key',
|
||||
'system.config.qrCodeConfig.appSecret': 'App Secret',
|
||||
'system.config.qrCodeConfig.callBack': 'CallBack',
|
||||
'system.config.qrCodeConfig.enable': 'Enable',
|
||||
'system.config.qrCodeConfig.valid': 'Valid',
|
||||
'system.config.qrCodeConfig.corpId.required': 'Corp Id is empty',
|
||||
'system.config.qrCodeConfig.agentId.required': 'Agent Id is empty',
|
||||
'system.config.qrCodeConfig.appKey.required': 'App Key is empty',
|
||||
'system.config.qrCodeConfig.appSecret.required': 'App Secret is empty',
|
||||
'system.config.qrCodeConfig.callBack.required': 'CallBack is empty',
|
||||
};
|
||||
|
|
|
@ -2,6 +2,7 @@ export default {
|
|||
'system.config.parameterConfig': '系统参数配置',
|
||||
'system.config.baseConfig': '基础设置',
|
||||
'system.config.pageConfig': '界面设置',
|
||||
'system.config.qrCodeConfig': '扫码登陆',
|
||||
'system.config.authConfig': '认证设置',
|
||||
'system.config.baseInfo': '基本信息',
|
||||
'system.config.update': '更新',
|
||||
|
@ -199,4 +200,16 @@ export default {
|
|||
'system.config.memoryCleanup.saveCount': '保留条数',
|
||||
'system.config.memoryCleanup.saveCountTip': '对系统内所有的项目生效,系统会在凌晨清除超出设置的变更历史记录',
|
||||
'system.config.memoryCleanup.numberTip': '系统默认最大保留条数为100000条,超过则为您保留全部记录',
|
||||
'system.config.qrCodeConfig.corpId': '企业ID',
|
||||
'system.config.qrCodeConfig.agentId': '应用ID',
|
||||
'system.config.qrCodeConfig.appKey': '应用key',
|
||||
'system.config.qrCodeConfig.appSecret': '应用密钥',
|
||||
'system.config.qrCodeConfig.callBack': '回调域名',
|
||||
'system.config.qrCodeConfig.enable': '是否开启',
|
||||
'system.config.qrCodeConfig.valid': '是否可用',
|
||||
'system.config.qrCodeConfig.corpId.required': '企业ID不能为空',
|
||||
'system.config.qrCodeConfig.agentId.required': '应用ID不能为空',
|
||||
'system.config.qrCodeConfig.appKey.required': '应用key不能为空',
|
||||
'system.config.qrCodeConfig.appSecret.required': '应用密钥不能为空',
|
||||
'system.config.qrCodeConfig.callBack.required': '回调域名不能为空',
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue