feat: 增加邮件配置

This commit is contained in:
fit2cloud-chenyw 2021-10-21 13:49:58 +08:00
parent ccc539f5b0
commit d3952387c1
21 changed files with 184 additions and 432 deletions

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>dataease-server</artifactId>
<groupId>io.dataease</groupId>
<version>1.3.0</version>
<version>1.4.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -201,7 +201,7 @@
<dependency>
<groupId>io.dataease</groupId>
<artifactId>dataease-plugin-interface</artifactId>
<version>1.3</version>
<version>1.4</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>

View File

@ -5,6 +5,8 @@ import io.dataease.auth.api.dto.CurrentUserDto;
import io.dataease.auth.api.dto.LoginDto;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import springfox.documentation.annotations.ApiIgnore;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@ -49,4 +51,8 @@ public interface AuthApi {
@PostMapping("/isOpenOidc")
boolean isOpenOidc();
@ApiIgnore
@PostMapping("/isPluginLoaded")
boolean isPluginLoaded();
}

View File

@ -184,6 +184,15 @@ public class AuthServer implements AuthApi {
return authUserService.supportOidc();
}
@Override
public boolean isPluginLoaded() {
Boolean licValid = PluginUtils.licValid();
if(!licValid) return false;
return authUserService.pluginLoaded();
}
/*@Override

View File

@ -29,6 +29,8 @@ public interface AuthUserService {
Boolean supportOidc();
Boolean pluginLoaded();
}

View File

@ -8,6 +8,7 @@ import io.dataease.base.mapper.ext.AuthMapper;
import io.dataease.auth.service.AuthUserService;
import io.dataease.commons.constants.AuthConstants;
import io.dataease.commons.utils.LogUtil;
import io.dataease.plugins.common.service.PluginCommonService;
import io.dataease.plugins.config.SpringContextUtil;
import io.dataease.plugins.xpack.ldap.service.LdapXpackService;
import io.dataease.plugins.xpack.oidc.service.OidcXpackService;
@ -137,5 +138,16 @@ public class AuthUserServiceImpl implements AuthUserService {
return oidcXpackService.isSuuportOIDC();
}
@Override
public Boolean pluginLoaded() {
Map<String, PluginCommonService> beansOfType = SpringContextUtil.getApplicationContext().getBeansOfType((PluginCommonService.class));
if(beansOfType.keySet().size() == 0) return false;
PluginCommonService pluginCommonService = SpringContextUtil.getBean(PluginCommonService.class);
if(ObjectUtils.isEmpty(pluginCommonService)) return false;
return pluginCommonService.isPluginLoaded();
}
}

View File

@ -2,6 +2,7 @@ package io.dataease.controller.sys;
import io.dataease.base.domain.SystemParameter;
import io.dataease.commons.constants.ParamConstants;
import io.dataease.controller.sys.response.MailInfo;
import io.dataease.dto.SystemParameterDTO;
import io.dataease.service.FileService;
import io.dataease.service.system.SystemParameterService;
@ -28,6 +29,12 @@ public class SystemParameterController {
@Resource
private FileService fileService;
@GetMapping("/mail/info")
public MailInfo mailInfo() {
return systemParameterService.mailInfo(ParamConstants.Classify.MAIL.getValue());
}
@PostMapping("/edit/email")
public void editMail(@RequestBody List<SystemParameter> systemParameter) {
systemParameterService.editMail(systemParameter);

View File

@ -0,0 +1,18 @@
package io.dataease.controller.sys.response;
import java.io.Serializable;
import lombok.Data;
@Data
public class MailInfo implements Serializable{
private String host;
private String port;
private String account;
private String password;
private String ssl;
private String tls;
private String recipient;
}

View File

@ -1,6 +1,5 @@
package io.dataease.service.system;
import com.alibaba.fastjson.JSON;
import io.dataease.base.domain.FileMetadata;
import io.dataease.base.domain.SystemParameter;
import io.dataease.base.domain.SystemParameterExample;
@ -11,6 +10,7 @@ import io.dataease.commons.exception.DEException;
import io.dataease.commons.utils.BeanUtils;
import io.dataease.commons.utils.EncryptUtils;
import io.dataease.commons.utils.LogUtil;
import io.dataease.controller.sys.response.MailInfo;
import io.dataease.dto.SystemParameterDTO;
import io.dataease.i18n.Translator;
import io.dataease.service.FileService;
@ -47,6 +47,34 @@ public class SystemParameterService {
return extSystemParameterMapper.email();
}
public MailInfo mailInfo(String type) {
List<SystemParameter> paramList = this.getParamList(type);
MailInfo mailInfo = new MailInfo();
if (!CollectionUtils.isEmpty(paramList)) {
for (SystemParameter param : paramList) {
if (StringUtils.equals(param.getParamKey(), ParamConstants.MAIL.SERVER.getValue())) {
mailInfo.setHost(param.getParamValue());
} else if (StringUtils.equals(param.getParamKey(), ParamConstants.MAIL.PORT.getValue())) {
mailInfo.setPort(param.getParamValue());
} else if (StringUtils.equals(param.getParamKey(), ParamConstants.MAIL.ACCOUNT.getValue())) {
mailInfo.setAccount(param.getParamValue());
} else if (StringUtils.equals(param.getParamKey(), ParamConstants.MAIL.PASSWORD.getValue())) {
String password = EncryptUtils.aesDecrypt(param.getParamValue()).toString();
mailInfo.setPassword(password);
} else if (StringUtils.equals(param.getParamKey(), ParamConstants.MAIL.SSL.getValue())) {
mailInfo.setSsl(param.getParamValue());
} else if (StringUtils.equals(param.getParamKey(), ParamConstants.MAIL.TLS.getValue())) {
mailInfo.setTls(param.getParamValue());
} else if (StringUtils.equals(param.getParamKey(), ParamConstants.MAIL.RECIPIENTS.getValue())) {
mailInfo.setRecipient(param.getParamValue());
}
}
}
return mailInfo;
}
public String getSystemLanguage() {
String result = StringUtils.EMPTY;
SystemParameterExample example = new SystemParameterExample();
@ -120,7 +148,7 @@ public class SystemParameterService {
try {
helper = new MimeMessageHelper(mimeMessage, true);
helper.setFrom(javaMailSender.getUsername());
helper.setSubject("MeterSphere测试邮件 " );
helper.setSubject("DataEase测试邮件 " );
helper.setText("这是一封测试邮件,邮件发送成功", true);
helper.setTo(recipients);
javaMailSender.send(mimeMessage);

View File

@ -5,3 +5,7 @@ UPDATE `chart_view` SET `render` = 'antv' WHERE `type` = 'liquid';
ALTER TABLE `panel_link` ADD COLUMN `over_time` bigint(13) NULL DEFAULT NULL COMMENT '有效截止时间' AFTER `pwd`;
BEGIN;
INSERT INTO `sys_menu` VALUES (6, 1, 0, 1, '系统参数', 'system-param', 'system/SysParam/index', 6, 'sys-tools', 'system-param', b'0', b'0', b'0', NULL, NULL, NULL, NULL, NULL);
COMMIT;

View File

@ -0,0 +1,30 @@
import request from '@/utils/request'
export function validate(data) {
return request({
url: '/system/testConnection',
method: 'post',
timeout: 30000,
loading: true,
data
})
}
export function emailInfo() {
return request({
url: '/system/mail/info',
method: 'get',
loading: true
})
}
export function updateInfo(data) {
return request({
url: '/system/edit/email',
method: 'post',
loading: true,
data
})
}

View File

@ -64,3 +64,10 @@ export function oidcStatus() {
method: 'post'
})
}
export function pluginLoaded() {
return request({
url: '/api/auth/isPluginLoaded',
method: 'post'
})
}

View File

@ -1,5 +1,5 @@
<template>
<div v-loading="result.loading">
<div>
<!--邮件表单-->
<el-form
ref="formInline"
@ -98,7 +98,7 @@
<script>
import { post, get } from '@/api/commonAjax'
import { emailInfo, updateInfo, validate } from '@/api/system/email'
export default {
name: 'EmailSetting',
@ -107,7 +107,6 @@ export default {
formInline: {},
input: '',
visible: true,
result: {},
showEdit: true,
showSave: false,
showCancel: false,
@ -148,11 +147,10 @@ export default {
this.$refs.input = 'password'
},
query() {
this.result = get('/system/mail/info', response => {
emailInfo().then(response => {
this.formInline = response.data
this.formInline.ssl = this.formInline.ssl === 'true'
this.formInline.tls = this.formInline.tls === 'true'
// console.log(this.formInline)
this.$nextTick(() => {
this.$refs.formInline.clearValidate()
})
@ -179,7 +177,7 @@ export default {
}
this.$refs[formInline].validate((valid) => {
if (valid) {
this.result = post('/system/testConnection', param, response => {
validate(param).then(response => {
this.$success(this.$t('commons.connection_successful'))
})
} else {
@ -211,7 +209,7 @@ export default {
this.$refs[formInline].validate(valid => {
if (valid) {
this.result = post('/system/edit/email', param, response => {
updateInfo(param).then(response => {
const flag = response.success
if (flag) {
this.$success(this.$t('commons.save_success'))
@ -220,7 +218,7 @@ export default {
}
})
} else {
return false
// this.result = false
}
})
},

View File

@ -0,0 +1,50 @@
<template>
<layout-content v-loading="$store.getters.loadingMap[$store.getters.currentPath]">
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane :lazy="true" :label="$t('system_parameter_setting.mailbox_service_settings')" name="first">
<email-setting />
</el-tab-pane>
<el-tab-pane v-if="isPluginLoaded" :lazy="true" :label="$t('sysParams.display')" name="second">
<plugin-com v-if="isPluginLoaded" ref="DisplaySetting" component-name="DisplaySetting" />
</el-tab-pane>
<el-tab-pane v-if="isPluginLoaded" :lazy="true" :label="$t('sysParams.ldap')" name="third">
<plugin-com v-if="isPluginLoaded" ref="DisplaySetting" component-name="LdapSetting" />
</el-tab-pane>
<el-tab-pane v-if="isPluginLoaded" :lazy="true" :label="$t('sysParams.oidc')" name="fourth">
<plugin-com v-if="isPluginLoaded" ref="DisplaySetting" component-name="SsoSetting" />
</el-tab-pane>
</el-tabs>
</layout-content>
</template>
<script>
import EmailSetting from './EmailSetting'
import LayoutContent from '@/components/business/LayoutContent'
import PluginCom from '@/views/system/plugin/PluginCom'
import { pluginLoaded } from '@/api/user'
export default {
components: { EmailSetting, LayoutContent, PluginCom },
data() {
return {
activeName: 'first',
isPluginLoaded: false
}
},
beforeCreate() {
pluginLoaded().then(res => {
this.isPluginLoaded = res.success && res.data
})
},
methods: {
handleClick(tab, event) {
console.log(tab, event)
}
}
}
</script>

View File

@ -1,21 +0,0 @@
<template>
<router-view />
</template>
<script>
export default ({
data() {
return {
}
},
created() {
this.$store.dispatch('app/toggleSideBarHide', false)
},
method: {
}
})
</script>

View File

@ -1,21 +0,0 @@
<template>
<h2>this is sso page</h2>
</template>
<script>
export default ({
data() {
return {
}
},
created() {
this.$store.dispatch('app/toggleSideBarHide', false)
},
method: {
}
})
</script>

View File

@ -1,10 +0,0 @@
<template>
<h2>
this is display settings page
</h2>
</template>
<script>
export default {
}
</script>

View File

@ -1,322 +0,0 @@
<template>
<div v-loading="$store.getters.loadingMap[$store.getters.currentPath]">
<el-form
ref="systemParams"
v-loading="$store.getters.loadingMap[$store.getters.currentPath]"
class="demo-form-inline"
:disabled="show"
size="small"
>
<el-row>
<el-col v-for="(param,index) in systemParams" :key="index">
<!--logo upload-->
<el-form-item
v-if="param.paramKey==='ui.logo'"
:label="$t('display.logo')"
>
<el-upload
v-loading="$store.getters.loadingMap[$store.getters.currentPath]"
style="float: right;margin-left: 10px"
class="upload-demo"
action=""
accept=".jpeg,.jpg,.png,.gif"
:on-exceed="handleExceed"
:before-upload="uploadValidate"
:on-error="handleError"
:show-file-list="false"
:file-list="filesTmp"
:http-request="uploadLogo"
>
<el-button style="display: inline-block" size="mini" type="success" plain>
{{ $t('commons.upload') }}
</el-button>
</el-upload>
<el-button
style="float:right;margin-top: 3px"
size="mini"
type="danger"
plain
@click="removeValue('ui.logo')"
>
{{ $t('commons.clear') }}
</el-button>
<el-input
v-model="param.fileName"
:disabled="true"
:placeholder="$t('display.advice_size')+'135px * 30px'"
/>
</el-form-item>
<!--logo upload-->
<el-form-item
v-if="param.paramKey==='ui.loginImage'"
:label="$t('display.loginImage')"
>
<el-upload
v-loading="$store.getters.loadingMap[$store.getters.currentPath]"
style="float: right;margin-left: 10px"
class="upload-demo"
action=""
accept=".jpeg,.jpg,.png,.gif"
:on-exceed="handleExceed"
:before-upload="uploadValidate"
:on-error="handleError"
:show-file-list="false"
:file-list="filesTmp"
:http-request="uploadLoginImage"
>
<el-button style="display: inline-block" size="mini" type="success" plain>
{{ $t('commons.upload') }}
</el-button>
</el-upload>
<el-button
style="float:right;margin-top: 3px"
size="mini"
type="danger"
plain
@click="removeValue('ui.loginImage')"
>
{{ $t('commons.clear') }}
</el-button>
<el-input
v-model="param.fileName"
:disabled="true"
:placeholder="$t('display.advice_size')+'500px * 450px'"
/>
</el-form-item>
<!--favicon upload-->
<el-form-item
v-if="param.paramKey==='ui.loginLogo'"
:label="$t('display.loginLogo')"
>
<el-upload
v-loading="$store.getters.loadingMap[$store.getters.currentPath]"
style="float: right;margin-left: 10px"
class="upload-demo"
action=""
accept=".jpeg,.jpg,.png,.gif"
:on-exceed="handleExceed"
:before-upload="uploadValidate"
:on-error="handleError"
:show-file-list="false"
:file-list="filesTmp"
:http-request="uploadLoginLogo"
>
<el-button style="display: inline-block" size="mini" type="success" plain>
{{ $t('commons.upload') }}
</el-button>
</el-upload>
<el-button
style="float:right;margin-top: 3px"
size="mini"
type="danger"
plain
@click="removeValue('ui.loginLogo')"
>
{{ $t('commons.clear') }}
</el-button>
<el-input
v-model="param.fileName"
:disabled="true"
:placeholder="$t('display.advice_size')+'135px * 30px'"
/>
</el-form-item>
<!--favicon upload-->
<el-form-item
v-show="showfavicon"
v-if="param.paramKey==='ui.favicon'"
:label="$t('display.favicon')"
>
<el-upload
v-loading="$store.getters.loadingMap[$store.getters.currentPath]"
style="float: right;margin-left: 10px"
class="upload-demo"
action=""
accept=".jpeg,.jpg,.png,.gif"
:on-exceed="handleExceed"
:before-upload="uploadValidate"
:on-error="handleError"
:show-file-list="false"
:file-list="filesTmp"
:http-request="uploadFavicon"
>
<el-button style="display: inline-block" size="mini" type="success" plain>
{{ $t('commons.upload') }}
</el-button>
</el-upload>
<el-button
style="float:right;margin-top: 3px"
size="mini"
type="danger"
plain
@click="removeValue('ui.favicon')"
>
{{ $t('commons.clear') }}
</el-button>
<el-input
v-model="param.fileName"
:disabled="true"
:placeholder="$t('display.advice_size')+'16px * 16px'"
/>
</el-form-item>
<!--ui.loginTitle-->
<el-form-item v-if="param.paramKey==='ui.loginTitle'" :label="$t('display.loginTitle')">
<el-input v-model="param.paramValue" placeholder="egDateEase" />
</el-form-item>
<!--ui.title-->
<el-form-item v-if="param.paramKey==='ui.title'" :label="$t('display.title')">
<el-input v-model="param.paramValue" placeholder="egDateEase" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<div>
<el-button v-if="showEdit" size="small" @click="edit">{{ $t('commons.edit') }}</el-button>
<el-button v-if="showSave" type="success" :disabled="disabledSave" size="small" @click="save">
{{ $t('commons.save') }}
</el-button>
<el-button v-if="showCancel" type="info" size="small" @click="cancel">{{ $t('commons.cancel') }}</el-button>
</div>
</div>
</template>
<script>
import { get, fileUpload } from '@/api/commonAjax'
export default {
name: 'UiSetting',
components: {
},
data() {
return {
filesTmp: [],
suffixes: new Set(['png', 'jpg', 'gif', 'jpeg']),
files: [],
systemParams: [],
systemParamsOld: [],
input: '',
visible: true,
result: {},
showEdit: true,
showSave: false,
showCancel: false,
show: true,
disabledConnection: false,
disabledSave: false,
loading: false,
rules: {
url: [
{
required: true,
message: 'Not Null',
trigger: ['change', 'blur']
}
]
},
showfavicon: false
}
},
created() {
this.query()
},
methods: {
query() {
get('/system/ui/info').then(res => {
this.systemParams = res.data
})
},
edit() {
this.showEdit = false
this.showSave = true
this.showCancel = true
this.show = false
},
save() {
this.showEdit = true
this.showCancel = false
this.showSave = false
this.show = true
this.systemParams.forEach((systemParam) => {
if (systemParam.file !== null) {
const file = systemParam.file
const name = file.name + ',' + systemParam.paramKey
const newfile = new File([file], name, { type: file.type })
this.files.push(newfile)
systemParam.file = null
}
})
fileUpload('/system/save/ui', null, this.files, { 'systemParams': this.systemParams }).then(response => {
if (response.success) {
this.query()//
this.$success(this.$t('commons.save_success'))
} else {
this.$message.error(this.$t('commons.save_failed'))
}
})
},
cancel() {
this.showEdit = true
this.showCancel = false
this.showSave = false
this.show = true
this.query()
},
handleExceed(files, fileList) {
this.$warning(this.$t('test_track.case.import.upload_limit_count'))
},
handleError() {
this.$warning(this.$t('test_track.case.import.upload_limit_count'))
},
uploadValidate(file) {
const suffix = file.name.substring(file.name.lastIndexOf('.') + 1)
if (!this.suffixes.has(suffix)) {
this.$warning(this.$t('test_track.case.import.upload_limit_format'))
return false
}
if (file.size / 1024 / 1024 > 5) {
this.$warning(this.$t('test_track.case.import.upload_limit_size'))
return false
}
this.errList = []
return true
},
uploadLogo(file) {
this.upload(file, 'ui.logo')
},
uploadFavicon(file) {
this.upload(file, 'ui.favicon')
},
uploadLoginImage(file) {
this.upload(file, 'ui.loginImage')
},
uploadLoginLogo(file) {
this.upload(file, 'ui.loginLogo')
},
upload(file, paramKey) {
this.systemParams.forEach((systemParam) => {
if (systemParam.paramKey === paramKey) {
systemParam.fileName = file.file.name
systemParam.file = file.file
}
})
},
removeValue(paramKey) {
this.systemParams.forEach((systemParam) => {
if (systemParam.paramKey === paramKey) {
systemParam.fileName = null
systemParam.file = null
}
})
}
}
}
</script>
<style scoped>
.el-form {
min-height: 300px;
}
</style>

View File

@ -1,45 +0,0 @@
<template>
<el-card>
<ui-setting v-if="!test" />
<!-- <el-tabs v-model="activeName" class="system-setting">
<el-tab-pane label="显示设置" name="ui">
<ui-setting />
</el-tab-pane>
<el-tab-pane :label="$t('system_parameter_setting.mailbox_service_settings')" name="email">
<email-setting />
</el-tab-pane>
</el-tabs> -->
<async-component v-if="test" url="http://localhost:8081/PluginDemo.js" @execute-axios="executeAxios" />
</el-card>
</template>
<script>
import UiSetting from './UiSetting'
import AsyncComponent from '@/components/AsyncComponent'
export default {
name: 'SystemParameterSetting',
components: {
UiSetting,
AsyncComponent
// 'MsDisplay': display.default,
// 'MsAuth': auth.default
},
data() {
return {
activeName: 'ui',
test: false
}
},
methods: {
// hasLicense
executeAxios(options) {
// console.log(options)
}
}
}
</script>
<style scoped>
</style>

View File

@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>io.dataease</groupId>
<artifactId>dataease-server</artifactId>
<version>1.3.0</version>
<version>1.4.0</version>
<packaging>pom</packaging>
<parent>