feat(系统设置): 新增系统参数配置扫码登陆平台页面

This commit is contained in:
guoyuqi 2024-06-06 16:10:03 +08:00 committed by 刘瑞斌
parent a4d9799a0f
commit e7304e5272
15 changed files with 864 additions and 0 deletions

View File

@ -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";

View File

@ -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=服务集成

View File

@ -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

View File

@ -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=服务集成

View File

@ -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=服務集成

View File

@ -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
}
]
},

View File

@ -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 });
}

View File

@ -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';

View File

@ -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[];

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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;
}
},
{

View File

@ -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',
};

View File

@ -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': '回调域名不能为空',
};