forked from github/dataease
fix: 系统管理文件名规范
This commit is contained in:
parent
c4f7fbc6c9
commit
daaf27746d
@ -140,10 +140,6 @@
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
<!-- <el-row v-if="loginTypes.includes(3)">
|
||||
<el-button class="pwd-tips" type="text">{{ $t('system_parameter_setting.cas_reset') + '[/cas/reset/{adminAcount}/{adminPwd}]' }}</el-button>
|
||||
</el-row> -->
|
||||
|
||||
<plugin-com
|
||||
v-if="isPluginLoaded"
|
||||
ref="LoginLimitSetting"
|
||||
@ -193,7 +189,7 @@
|
||||
import { basicInfo, updateInfo } from '@/api/system/basic'
|
||||
import { ldapStatus, oidcStatus, casStatus } from '@/api/user'
|
||||
import bus from '@/utils/bus'
|
||||
import operater from './operater'
|
||||
import operater from './Operater'
|
||||
import msgCfm from '@/components/msgCfm'
|
||||
import PluginCom from '@/views/system/plugin/PluginCom'
|
||||
export default {
|
||||
@ -386,14 +382,9 @@ export default {
|
||||
.then(() => {
|
||||
this.saveHandler(param)
|
||||
})
|
||||
.catch(() => {
|
||||
// this.$info(this.$t('commons.delete_cancel'))
|
||||
})
|
||||
return
|
||||
}
|
||||
this.saveHandler(param)
|
||||
} else {
|
||||
// this.result = false
|
||||
}
|
||||
})
|
||||
},
|
||||
|
@ -182,7 +182,7 @@
|
||||
<script>
|
||||
import { engineInfo, validate, save } from '@/api/system/engine'
|
||||
import i18n from '@/lang'
|
||||
import operater from './operater'
|
||||
import operater from './Operater'
|
||||
import msgCfm from '@/components/msgCfm'
|
||||
import dePwd from '@/components/deCustomCm/dePwd.vue'
|
||||
export default {
|
||||
|
@ -122,7 +122,6 @@
|
||||
</el-tooltip>
|
||||
</el-checkbox>
|
||||
</el-form-item>
|
||||
<!---->
|
||||
<template #footer />
|
||||
</el-form>
|
||||
</div>
|
||||
@ -130,7 +129,7 @@
|
||||
|
||||
<script>
|
||||
import { emailInfo, updateInfo, validate } from '@/api/system/email'
|
||||
import operater from './operater'
|
||||
import operater from './Operater'
|
||||
import msgCfm from '@/components/msgCfm'
|
||||
import dePwd from '@/components/deCustomCm/dePwd.vue'
|
||||
export default {
|
||||
@ -291,8 +290,6 @@ export default {
|
||||
this.$message.error(this.$t('commons.save_failed'))
|
||||
}
|
||||
})
|
||||
} else {
|
||||
// this.result = false
|
||||
}
|
||||
})
|
||||
},
|
||||
@ -306,6 +303,3 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
|
@ -1,6 +1,5 @@
|
||||
<template>
|
||||
<div>
|
||||
|
||||
<!--基础配置表单-->
|
||||
<el-form
|
||||
v-if="status !== 'empty' && status !== 'read-only'"
|
||||
@ -237,14 +236,10 @@ export default {
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
||||
treeDatas: function(val) {
|
||||
this.treeParams.data = val
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// this.query()
|
||||
},
|
||||
methods: {
|
||||
handleExceed(files, fileList) {
|
||||
this.$warning(this.$t('test_track.case.import.upload_limit_count'))
|
||||
@ -298,8 +293,6 @@ export default {
|
||||
this.$refs[formInline].validate(valid => {
|
||||
if (valid) {
|
||||
this.saveHandler(param)
|
||||
} else {
|
||||
// this.result = false
|
||||
}
|
||||
})
|
||||
},
|
||||
|
@ -297,7 +297,3 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
472
frontend/src/views/system/sysParam/BasicSetting.vue
Normal file
472
frontend/src/views/system/sysParam/BasicSetting.vue
Normal file
@ -0,0 +1,472 @@
|
||||
<template>
|
||||
<div>
|
||||
<operater title="system_parameter_setting.basic_setting">
|
||||
<deBtn
|
||||
v-if="showEdit"
|
||||
type="primary"
|
||||
@click="edit"
|
||||
>{{
|
||||
$t("commons.edit")
|
||||
}}</deBtn>
|
||||
<deBtn
|
||||
v-if="showCancel"
|
||||
secondary
|
||||
@click="cancel"
|
||||
>{{
|
||||
$t("commons.cancel")
|
||||
}}</deBtn>
|
||||
<deBtn
|
||||
v-if="showSave"
|
||||
type="primary"
|
||||
:disabled="disabledSave"
|
||||
size="small"
|
||||
@click="save('formInline')"
|
||||
>
|
||||
{{ $t("commons.save") }}
|
||||
</deBtn>
|
||||
</operater>
|
||||
|
||||
<!--基础配置表单-->
|
||||
<el-form
|
||||
ref="formInline"
|
||||
v-loading="loading"
|
||||
:model="formInline"
|
||||
:rules="rules"
|
||||
class="demo-form-inline de-form-item"
|
||||
:disabled="show"
|
||||
label-width="80px"
|
||||
label-position="right"
|
||||
size="small"
|
||||
>
|
||||
<el-form-item prop="frontTimeOut">
|
||||
<template slot="label">
|
||||
{{ $t('system_parameter_setting.request_timeout') }}
|
||||
<el-tooltip
|
||||
class="item"
|
||||
effect="dark"
|
||||
:content="$t('system_parameter_setting.front_time_out')"
|
||||
placement="top"
|
||||
>
|
||||
<i class="el-icon-warning-outline tips" />
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-input
|
||||
v-model="formInline.frontTimeOut"
|
||||
:placeholder="$t('system_parameter_setting.empty_front')"
|
||||
><template
|
||||
slot="append"
|
||||
>{{ $t("panel.second") }}</template></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="$t('system_parameter_setting.message_retention_time')"
|
||||
prop="msgTimeOut"
|
||||
>
|
||||
<el-input
|
||||
v-model="formInline.msgTimeOut"
|
||||
:placeholder="$t('system_parameter_setting.empty_msg')"
|
||||
><template
|
||||
slot="append"
|
||||
>{{ $t('components.day') }}</template></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('system_parameter_setting.ds_check_time')">
|
||||
<el-form
|
||||
:inline="true"
|
||||
:disabled="show"
|
||||
class="demo-form-inline-ds"
|
||||
>
|
||||
|
||||
<el-form-item>
|
||||
<el-input
|
||||
v-model="formInline.dsCheckInterval"
|
||||
size="mini"
|
||||
type="number"
|
||||
min="1"
|
||||
@change="onSimpleCronChange()"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item class="form-item">
|
||||
<el-select
|
||||
v-model="formInline.dsCheckIntervalType"
|
||||
filterable
|
||||
size="mini"
|
||||
@change="onSimpleCronChange()"
|
||||
>
|
||||
<el-option
|
||||
:label="$t('cron.minute_default')"
|
||||
value="minute"
|
||||
/>
|
||||
<el-option
|
||||
:label="$t('cron.hour_default')"
|
||||
value="hour"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
class="form-item"
|
||||
:label="$t('cron.every_exec')"
|
||||
/>
|
||||
</el-form>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item
|
||||
v-if="loginTypes.length > 1"
|
||||
:label="$t('system_parameter_setting.login_type')"
|
||||
prop="loginType"
|
||||
>
|
||||
<el-radio-group v-model="formInline.loginType">
|
||||
<el-radio
|
||||
:label="0"
|
||||
size="mini"
|
||||
>{{
|
||||
$t("login.default_login")
|
||||
}}</el-radio>
|
||||
<el-radio
|
||||
v-if="loginTypes.includes(1)"
|
||||
:label="1"
|
||||
size="mini"
|
||||
>LDAP</el-radio>
|
||||
<el-radio
|
||||
v-if="loginTypes.includes(2)"
|
||||
:label="2"
|
||||
size="mini"
|
||||
>OIDC</el-radio>
|
||||
<el-radio
|
||||
v-if="loginTypes.includes(3)"
|
||||
:label="3"
|
||||
size="mini"
|
||||
>CAS</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
<plugin-com
|
||||
v-if="isPluginLoaded"
|
||||
ref="LoginLimitSetting"
|
||||
:form="formInline"
|
||||
component-name="LoginLimitSetting"
|
||||
/>
|
||||
|
||||
<el-form-item
|
||||
:label="
|
||||
$t('commons.yes') + $t('commons.no') + $t('display.openMarketPage')
|
||||
"
|
||||
>
|
||||
<el-radio-group v-model="formInline.openMarketPage">
|
||||
<el-radio
|
||||
label="true"
|
||||
size="mini"
|
||||
>{{ $t("commons.yes") }}</el-radio>
|
||||
<el-radio
|
||||
label="false"
|
||||
size="mini"
|
||||
>{{ $t("commons.no") }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item
|
||||
:label="
|
||||
$t('commons.yes') + $t('commons.no') + $t('display.openHomePage')
|
||||
"
|
||||
prop="openHomePage"
|
||||
>
|
||||
<el-radio-group v-model="formInline.openHomePage">
|
||||
<el-radio
|
||||
label="true"
|
||||
size="mini"
|
||||
>{{ $t("commons.yes") }}</el-radio>
|
||||
<el-radio
|
||||
label="false"
|
||||
size="mini"
|
||||
>{{ $t("commons.no") }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { basicInfo, updateInfo } from '@/api/system/basic'
|
||||
import { ldapStatus, oidcStatus, casStatus } from '@/api/user'
|
||||
import bus from '@/utils/bus'
|
||||
import operater from './Operater'
|
||||
import msgCfm from '@/components/msgCfm'
|
||||
import PluginCom from '@/views/system/plugin/PluginCom'
|
||||
export default {
|
||||
name: 'EmailSetting',
|
||||
components: {
|
||||
operater,
|
||||
PluginCom
|
||||
},
|
||||
mixins: [msgCfm],
|
||||
props: {
|
||||
isPluginLoaded: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
formInline: {},
|
||||
showEdit: true,
|
||||
showSave: false,
|
||||
showCancel: false,
|
||||
show: true,
|
||||
disabledSave: false,
|
||||
loading: false,
|
||||
loginTypes: [0],
|
||||
rules: {
|
||||
frontTimeOut: [
|
||||
{
|
||||
pattern: '^([0-9]|\\b[1-9]\\d\\b|\\b[1-2]\\d\\d\\b|\\b300\\b)$',
|
||||
message: this.$t('system_parameter_setting.front_error'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
msgTimeOut: [
|
||||
{
|
||||
pattern: '^([1-9]|[1-9][0-9]|[1-2][0-9][0-9]|3[0-5][0-9]|36[0-5])$',
|
||||
message: this.$t('system_parameter_setting.msg_error'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
limitTimes: [
|
||||
|
||||
{ validator: this.validateNumber, trigger: 'blur' }
|
||||
],
|
||||
relieveTimes: [
|
||||
{ validator: this.validateNumber, trigger: 'blur' }
|
||||
]
|
||||
},
|
||||
originLoginType: null
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
beforeCreate() {
|
||||
ldapStatus().then((res) => {
|
||||
if (res.success && res.data) {
|
||||
this.loginTypes.push(1)
|
||||
}
|
||||
})
|
||||
|
||||
oidcStatus().then((res) => {
|
||||
if (res.success && res.data) {
|
||||
this.loginTypes.push(2)
|
||||
}
|
||||
})
|
||||
|
||||
casStatus().then((res) => {
|
||||
if (res.success && res.data) {
|
||||
this.loginTypes.push(3)
|
||||
}
|
||||
})
|
||||
},
|
||||
created() {
|
||||
this.query()
|
||||
},
|
||||
methods: {
|
||||
validateNumber(rule, value, callback) {
|
||||
if (value != null && value !== '') {
|
||||
const reg = new RegExp('^([1-9]|[1-9]\\d|100)$')
|
||||
if (!reg.test(value)) {
|
||||
const msg = this.$t('system_parameter_setting.relieve_times_error')
|
||||
callback(new Error(msg))
|
||||
return
|
||||
}
|
||||
}
|
||||
callback()
|
||||
},
|
||||
query() {
|
||||
basicInfo().then((response) => {
|
||||
this.formInline = response.data
|
||||
|
||||
if (this.formInline && !this.formInline.loginType) {
|
||||
this.formInline.loginType = 0
|
||||
}
|
||||
if (!this.originLoginType) {
|
||||
this.originLoginType = this.formInline.loginType
|
||||
}
|
||||
this.formInline.open = (this.formInline.open && this.formInline.open === 'true')
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.$refs.formInline.clearValidate()
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
edit() {
|
||||
this.showEdit = false
|
||||
this.showSave = true
|
||||
this.showCancel = true
|
||||
this.show = false
|
||||
},
|
||||
save(formInline) {
|
||||
const param = [
|
||||
{
|
||||
paramKey: 'basic.frontTimeOut',
|
||||
paramValue: this.formInline.frontTimeOut,
|
||||
type: 'text',
|
||||
sort: 1
|
||||
},
|
||||
{
|
||||
paramKey: 'basic.msgTimeOut',
|
||||
paramValue: this.formInline.msgTimeOut,
|
||||
type: 'text',
|
||||
sort: 2
|
||||
},
|
||||
{
|
||||
paramKey: 'basic.loginType',
|
||||
paramValue: this.formInline.loginType,
|
||||
type: 'text',
|
||||
sort: 3
|
||||
},
|
||||
{
|
||||
paramKey: 'basic.dsCheckInterval',
|
||||
paramValue: this.formInline.dsCheckInterval,
|
||||
type: 'text',
|
||||
sort: 4
|
||||
},
|
||||
{
|
||||
paramKey: 'basic.dsCheckIntervalType',
|
||||
paramValue: this.formInline.dsCheckIntervalType,
|
||||
type: 'text',
|
||||
sort: 5
|
||||
},
|
||||
{
|
||||
paramKey: 'ui.openHomePage',
|
||||
paramValue: this.formInline.openHomePage,
|
||||
type: 'text',
|
||||
sort: 13
|
||||
},
|
||||
{
|
||||
paramKey: 'ui.openMarketPage',
|
||||
paramValue: this.formInline.openMarketPage,
|
||||
type: 'text',
|
||||
sort: 14
|
||||
},
|
||||
|
||||
{
|
||||
paramKey: 'loginlimit.limitTimes',
|
||||
paramValue: this.formInline.limitTimes,
|
||||
type: 'text',
|
||||
sort: 1
|
||||
},
|
||||
{
|
||||
paramKey: 'loginlimit.relieveTimes',
|
||||
paramValue: this.formInline.relieveTimes,
|
||||
type: 'text',
|
||||
sort: 2
|
||||
},
|
||||
{
|
||||
paramKey: 'loginlimit.open',
|
||||
paramValue: this.formInline.open,
|
||||
type: 'text',
|
||||
sort: 3
|
||||
}
|
||||
]
|
||||
|
||||
this.$refs[formInline].validate((valid) => {
|
||||
if (valid) {
|
||||
const needWarn =
|
||||
this.formInline.loginType === 3 && this.originLoginType !== 3
|
||||
if (needWarn) {
|
||||
this.$confirm(
|
||||
this.$t('system_parameter_setting.cas_selected_warn'),
|
||||
'',
|
||||
{
|
||||
confirmButtonText: this.$t('commons.confirm'),
|
||||
cancelButtonText: this.$t('commons.cancel'),
|
||||
type: 'warning'
|
||||
}
|
||||
)
|
||||
.then(() => {
|
||||
this.saveHandler(param)
|
||||
})
|
||||
return
|
||||
}
|
||||
this.saveHandler(param)
|
||||
}
|
||||
})
|
||||
},
|
||||
saveHandler(param) {
|
||||
updateInfo(param).then((response) => {
|
||||
const flag = response.success
|
||||
if (flag) {
|
||||
if (response.data && response.data.needLogout) {
|
||||
const casEnable = response.data.casEnable
|
||||
bus.$emit('sys-logout', { casEnable })
|
||||
return
|
||||
}
|
||||
this.openMessageSuccess('commons.save_success')
|
||||
this.showEdit = true
|
||||
this.showCancel = false
|
||||
this.showSave = false
|
||||
this.show = true
|
||||
window.location.reload()
|
||||
} else {
|
||||
this.openMessageSuccess('commons.save_failed', 'error')
|
||||
}
|
||||
})
|
||||
},
|
||||
cancel() {
|
||||
this.showEdit = true
|
||||
this.showCancel = false
|
||||
this.showSave = false
|
||||
this.show = true
|
||||
this.query()
|
||||
},
|
||||
onSimpleCronChange() {
|
||||
if (this.formInline.dsCheckIntervalType === 'minute') {
|
||||
const pattern = '^([1-9]|[1-5][0-9])$'
|
||||
if (!new RegExp(pattern).test(this.formInline.dsCheckInterval)) {
|
||||
this.$message({ message: this.$t('cron.minute_limit'), type: 'warning', showClose: true })
|
||||
this.formInline.dsCheckInterval = 1
|
||||
}
|
||||
return
|
||||
}
|
||||
if (this.formInline.dsCheckIntervalType === 'hour') {
|
||||
const pattern = '^([1-9]|[1-2][0-3])$'
|
||||
if (!new RegExp(pattern).test(this.formInline.dsCheckInterval)) {
|
||||
this.$message({ message: this.$t('cron.hour_limit'), type: 'warning', showClose: true })
|
||||
this.formInline.dsCheckInterval = 1
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.demo-form-inline {
|
||||
.tips {
|
||||
margin-left: 2px;
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.el-radio:not(:last-child) {
|
||||
margin-right: 0;
|
||||
width: 156px;
|
||||
}
|
||||
}
|
||||
|
||||
.demo-form-inline-ds {
|
||||
.el-form-item {
|
||||
margin-bottom: 0px !important;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
<style lang="scss">
|
||||
.de-i118 {
|
||||
.el-form-item__label::after {
|
||||
display: none;
|
||||
}
|
||||
.is-require::after {
|
||||
content: "*";
|
||||
color: #f54a45;
|
||||
margin-left: 2px;
|
||||
}
|
||||
}
|
||||
</style>
|
461
frontend/src/views/system/sysParam/ClusterModeSetting.vue
Normal file
461
frontend/src/views/system/sysParam/ClusterModeSetting.vue
Normal file
@ -0,0 +1,461 @@
|
||||
<template>
|
||||
<div>
|
||||
<operater title="system_parameter_setting.engine_mode_setting">
|
||||
<deBtn
|
||||
v-if="showCancel"
|
||||
secondary
|
||||
@click="cancel"
|
||||
>
|
||||
{{ $t("commons.cancel") }}
|
||||
</deBtn>
|
||||
<deBtn
|
||||
secondary
|
||||
@click="validaDatasource"
|
||||
>
|
||||
{{ $t("commons.validate") }}
|
||||
</deBtn>
|
||||
<deBtn
|
||||
v-if="showEdit"
|
||||
type="primary"
|
||||
@click="edit"
|
||||
>
|
||||
{{ $t("commons.edit") }}
|
||||
</deBtn>
|
||||
<deBtn
|
||||
v-if="showSave"
|
||||
type="primary"
|
||||
@click="save"
|
||||
>
|
||||
{{ $t("commons.save") }}
|
||||
</deBtn>
|
||||
</operater>
|
||||
<el-form
|
||||
ref="form"
|
||||
v-loading="loading"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
class="de-form-item"
|
||||
:disabled="show"
|
||||
label-width="180px"
|
||||
label-position="top"
|
||||
size="small"
|
||||
>
|
||||
<el-form-item
|
||||
:label="$t('datasource.doris_host')"
|
||||
prop="configuration.host"
|
||||
>
|
||||
<el-input v-model="form.configuration.host" />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="$t('datasource.data_base')"
|
||||
prop="configuration.dataBase"
|
||||
>
|
||||
<el-input v-model="form.configuration.dataBase" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('datasource.user_name')">
|
||||
<el-input v-model="form.configuration.username" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('datasource.password')">
|
||||
<dePwd v-model="form.configuration.password" />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="$t('datasource.query_port')"
|
||||
prop="configuration.port"
|
||||
>
|
||||
<el-input-number
|
||||
v-model="form.configuration.port"
|
||||
controls-position="right"
|
||||
autocomplete="off"
|
||||
type="number"
|
||||
min="0"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="$t('datasource.http_port')"
|
||||
prop="configuration.httpPort"
|
||||
>
|
||||
<el-input-number
|
||||
v-model="form.configuration.httpPort"
|
||||
controls-position="right"
|
||||
autocomplete="off"
|
||||
type="number"
|
||||
min="0"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<span
|
||||
class="de-expand"
|
||||
@click="showPriority = !showPriority"
|
||||
>{{ $t("datasource.priority")
|
||||
}}<i
|
||||
v-if="showPriority"
|
||||
class="el-icon-arrow-up"
|
||||
/>
|
||||
<i
|
||||
v-else
|
||||
class="el-icon-arrow-down"
|
||||
/></span>
|
||||
<template v-if="showPriority">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<el-form-item
|
||||
:label="$t('datasource.replication_num')"
|
||||
prop="configuration.replicationNum"
|
||||
>
|
||||
<el-input-number
|
||||
v-model="form.configuration.replicationNum"
|
||||
controls-position="right"
|
||||
autocomplete="off"
|
||||
type="number"
|
||||
min="1"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item
|
||||
:label="$t('datasource.bucket_num')"
|
||||
prop="configuration.bucketNum"
|
||||
>
|
||||
<el-input-number
|
||||
v-model="form.configuration.bucketNum"
|
||||
controls-position="right"
|
||||
autocomplete="off"
|
||||
type="number"
|
||||
min="1"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<el-form-item
|
||||
:label="$t('datasource.initial_pool_size')"
|
||||
prop="configuration.initialPoolSize"
|
||||
>
|
||||
<el-input-number
|
||||
v-model="form.configuration.initialPoolSize"
|
||||
controls-position="right"
|
||||
autocomplete="off"
|
||||
type="number"
|
||||
min="0"
|
||||
size="small"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item
|
||||
:label="$t('datasource.min_pool_size')"
|
||||
prop="configuration.minPoolSize"
|
||||
>
|
||||
<el-input-number
|
||||
v-model="form.configuration.minPoolSize"
|
||||
controls-position="right"
|
||||
autocomplete="off"
|
||||
type="number"
|
||||
min="0"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<el-form-item
|
||||
:label="$t('datasource.max_pool_size')"
|
||||
prop="configuration.maxPoolSize"
|
||||
>
|
||||
<el-input-number
|
||||
v-model="form.configuration.maxPoolSize"
|
||||
controls-position="right"
|
||||
autocomplete="off"
|
||||
type="number"
|
||||
min="0"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { engineInfo, validate, save } from '@/api/system/engine'
|
||||
import i18n from '@/lang'
|
||||
import operater from './Operater'
|
||||
import msgCfm from '@/components/msgCfm'
|
||||
import dePwd from '@/components/deCustomCm/dePwd.vue'
|
||||
export default {
|
||||
name: 'ClusterMode',
|
||||
components: {
|
||||
operater,
|
||||
dePwd
|
||||
},
|
||||
mixins: [msgCfm],
|
||||
data() {
|
||||
return {
|
||||
showPriority: false,
|
||||
form: {
|
||||
type: 'engine_doris',
|
||||
configuration: {
|
||||
host: '',
|
||||
dataBase: '',
|
||||
username: '',
|
||||
password: '',
|
||||
port: '',
|
||||
httpPort: 8030,
|
||||
extraParams:
|
||||
'characterEncoding=UTF-8&connectTimeout=5000&useSSL=false&allowPublicKeyRetrieval=true&zeroDateTimeBehavior=convertToNull',
|
||||
replicationNum: 1,
|
||||
bucketNum: 10,
|
||||
minPoolSize: 5,
|
||||
maxPoolSize: 50,
|
||||
initialPoolSize: 5
|
||||
}
|
||||
},
|
||||
originConfiguration: {
|
||||
host: '',
|
||||
dataBase: '',
|
||||
username: '',
|
||||
password: '',
|
||||
port: '',
|
||||
httpPort: 8030,
|
||||
extraParams:
|
||||
'characterEncoding=UTF-8&connectTimeout=5000&useSSL=false&allowPublicKeyRetrieval=true&zeroDateTimeBehavior=convertToNull',
|
||||
replicationNum: 1,
|
||||
bucketNum: 10,
|
||||
minPoolSize: 5,
|
||||
maxPoolSize: 50,
|
||||
initialPoolSize: 5
|
||||
},
|
||||
input: '',
|
||||
visible: true,
|
||||
showEdit: true,
|
||||
showSave: false,
|
||||
showCancel: false,
|
||||
show: true,
|
||||
disabledConnection: false,
|
||||
disabledSave: false,
|
||||
loading: false,
|
||||
rules: {
|
||||
'configuration.host': [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('datasource.please_input_host'),
|
||||
trigger: ['change', 'blur']
|
||||
}
|
||||
],
|
||||
'configuration.port': [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('datasource.please_input_port'),
|
||||
trigger: ['change', 'blur']
|
||||
}
|
||||
],
|
||||
'configuration.httpPort': [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('datasource.please_input_port'),
|
||||
trigger: ['change', 'blur']
|
||||
}
|
||||
],
|
||||
'configuration.dataBase': [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('datasource.please_input_data_base'),
|
||||
trigger: ['change', 'blur']
|
||||
}
|
||||
],
|
||||
'configuration.replicationNum': [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('datasource.please_input_replication_num'),
|
||||
trigger: ['change', 'blur']
|
||||
}
|
||||
],
|
||||
'configuration.bucketNum': [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('datasource.please_input_bucket_num'),
|
||||
trigger: ['change', 'blur']
|
||||
}
|
||||
],
|
||||
'configuration.minPoolSize': [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('datasource.commons.cannot_be_null'),
|
||||
trigger: ['change', 'blur']
|
||||
}
|
||||
],
|
||||
'configuration.initialPoolSize': [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('commons.cannot_be_null'),
|
||||
trigger: ['change', 'blur']
|
||||
}
|
||||
],
|
||||
'configuration.maxPoolSize': [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('datasource.commons.cannot_be_null'),
|
||||
trigger: ['change', 'blur']
|
||||
}
|
||||
]
|
||||
},
|
||||
allTypes: [
|
||||
{
|
||||
name: 'engine_mysql',
|
||||
label: 'MySQL',
|
||||
type: 'jdbc',
|
||||
extraParams:
|
||||
'characterEncoding=UTF-8&connectTimeout=5000&useSSL=false&allowPublicKeyRetrieval=true'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.query()
|
||||
},
|
||||
methods: {
|
||||
query() {
|
||||
engineInfo().then((response) => {
|
||||
if (response.data.id) {
|
||||
this.form = JSON.parse(JSON.stringify(response.data))
|
||||
this.form.configuration = JSON.parse(this.form.configuration)
|
||||
this.originConfiguration = JSON.parse(
|
||||
JSON.stringify(this.form.configuration)
|
||||
)
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
this.$refs.form.clearValidate()
|
||||
})
|
||||
})
|
||||
},
|
||||
edit() {
|
||||
this.showEdit = false
|
||||
this.showSave = true
|
||||
this.showCancel = true
|
||||
this.show = false
|
||||
},
|
||||
save() {
|
||||
if (
|
||||
this.form.configuration.dataSourceType === 'jdbc' &&
|
||||
(this.form.configuration.port <= 0 ||
|
||||
this.form.configuration.httpPort <= 0)
|
||||
) {
|
||||
this.$message.error(i18n.t('datasource.port_no_less_then_0'))
|
||||
return
|
||||
}
|
||||
if (
|
||||
this.form.configuration.initialPoolSize < 0 ||
|
||||
this.form.configuration.minPoolSize < 0 ||
|
||||
this.form.configuration.maxPoolSize < 0
|
||||
) {
|
||||
this.$message.error(i18n.t('datasource.no_less_then_0'))
|
||||
return
|
||||
}
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (!valid) {
|
||||
return false
|
||||
}
|
||||
const form = JSON.parse(JSON.stringify(this.form))
|
||||
form.configuration = JSON.stringify(form.configuration)
|
||||
save(form).then((res) => {
|
||||
this.showEdit = true
|
||||
this.showCancel = false
|
||||
this.showSave = false
|
||||
this.show = true
|
||||
this.originConfiguration = JSON.parse(
|
||||
JSON.stringify(this.form.configuration)
|
||||
)
|
||||
this.openMessageSuccess('commons.save_success')
|
||||
})
|
||||
})
|
||||
},
|
||||
cancel() {
|
||||
this.showEdit = true
|
||||
this.showCancel = false
|
||||
this.showSave = false
|
||||
this.show = true
|
||||
this.form.configuration = JSON.parse(
|
||||
JSON.stringify(this.originConfiguration)
|
||||
)
|
||||
},
|
||||
changeType() {
|
||||
for (let i = 0; i < this.allTypes.length; i++) {
|
||||
if (this.allTypes[i].name === this.form.type) {
|
||||
this.form.configuration.dataSourceType = this.allTypes[i].type
|
||||
this.form.configuration.extraParams = this.allTypes[i].extraParams
|
||||
}
|
||||
}
|
||||
},
|
||||
validaDatasource() {
|
||||
if (!this.form.configuration.schema && this.form.type === 'oracle') {
|
||||
this.$message.error(i18n.t('datasource.please_choose_schema'))
|
||||
return
|
||||
}
|
||||
if (
|
||||
this.form.configuration.dataSourceType === 'jdbc' &&
|
||||
(this.form.configuration.port <= 0 ||
|
||||
this.form.configuration.httpPort <= 0)
|
||||
) {
|
||||
this.$message.error(i18n.t('datasource.port_no_less_then_0'))
|
||||
return
|
||||
}
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
const data = JSON.parse(JSON.stringify(this.form))
|
||||
data.configuration = JSON.stringify(data.configuration)
|
||||
validate(data).then((res) => {
|
||||
if (res.success) {
|
||||
this.openMessageSuccess('datasource.validate_success')
|
||||
} else {
|
||||
if (res.message.length < 2500) {
|
||||
this.$error(res.message)
|
||||
} else {
|
||||
this.$error(res.message.substring(0, 2500) + '......')
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.de-expand {
|
||||
font-family: PingFang SC;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 22px;
|
||||
color: #3370ff;
|
||||
cursor: pointer;
|
||||
margin: 12px 0 16px 0;
|
||||
display: inline-block;
|
||||
}
|
||||
.el-input-number {
|
||||
width: 100%;
|
||||
::v-deep .el-input__inner {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
::v-deep.el-input-number__decrease,
|
||||
::v-deep.el-input-number__increase {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
&.is-disabled {
|
||||
.el-input-number__decrease {
|
||||
border-right-color: #e4e7ed;
|
||||
}
|
||||
|
||||
.el-input-number__increase {
|
||||
border-bottom-color: #e4e7ed;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
305
frontend/src/views/system/sysParam/EmailSetting.vue
Normal file
305
frontend/src/views/system/sysParam/EmailSetting.vue
Normal file
@ -0,0 +1,305 @@
|
||||
<template>
|
||||
<div>
|
||||
<operater title="system_parameter_setting.mailbox_service_settings">
|
||||
<deBtn
|
||||
v-if="showCancel"
|
||||
secondary
|
||||
@click="cancel"
|
||||
>{{
|
||||
$t("commons.cancel")
|
||||
}}</deBtn>
|
||||
<deBtn
|
||||
secondary
|
||||
:disabled="disabledConnection"
|
||||
@click="testConnection('formInline')"
|
||||
>
|
||||
{{ $t("system_parameter_setting.test_connection") }}
|
||||
</deBtn>
|
||||
<deBtn
|
||||
v-if="showEdit"
|
||||
type="primary"
|
||||
@click="edit"
|
||||
>{{
|
||||
$t("commons.edit")
|
||||
}}</deBtn>
|
||||
<deBtn
|
||||
v-if="showSave"
|
||||
type="primary"
|
||||
:disabled="disabledSave"
|
||||
|
||||
@click="save('formInline')"
|
||||
>
|
||||
{{ $t("commons.save") }}
|
||||
</deBtn>
|
||||
</operater>
|
||||
<!--邮件表单-->
|
||||
<el-form
|
||||
ref="formInline"
|
||||
v-loading="loading"
|
||||
:model="formInline"
|
||||
:rules="rules"
|
||||
class="demo-form-inline de-form-item"
|
||||
:disabled="show"
|
||||
size="small"
|
||||
>
|
||||
<el-form-item
|
||||
:label="$t('system_parameter_setting.SMTP_host')"
|
||||
prop="host"
|
||||
>
|
||||
<el-input
|
||||
v-model="formInline.host"
|
||||
:placeholder="$t('system_parameter_setting.SMTP_host')"
|
||||
@input="change()"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="$t('system_parameter_setting.SMTP_port')"
|
||||
prop="port"
|
||||
>
|
||||
<el-input
|
||||
v-model="formInline.port"
|
||||
:placeholder="$t('system_parameter_setting.SMTP_port')"
|
||||
@input="change()"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="$t('system_parameter_setting.SMTP_account')"
|
||||
prop="account"
|
||||
>
|
||||
<el-input
|
||||
v-model="formInline.account"
|
||||
:placeholder="$t('system_parameter_setting.SMTP_account')"
|
||||
@input="change()"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="$t('system_parameter_setting.SMTP_password')"
|
||||
prop="password"
|
||||
>
|
||||
<dePwd
|
||||
v-model="formInline.password"
|
||||
:placeholder="$t('system_parameter_setting.SMTP_password')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('system_parameter_setting.test_recipients')">
|
||||
<template slot="label">
|
||||
{{ $t("system_parameter_setting.test_recipients") }}
|
||||
<el-tooltip
|
||||
class="item"
|
||||
effect="dark"
|
||||
:content="$t('system_parameter_setting.test_mail_recipient')"
|
||||
placement="top"
|
||||
>
|
||||
<i class="el-icon-warning-outline tips-not-absolute" />
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<dePwd
|
||||
v-model="formInline.recipient"
|
||||
:placeholder="$t('system_parameter_setting.test_recipients')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="邮箱服务器配置">
|
||||
<el-checkbox v-model="formInline.ssl">{{ $t('chart.open') }}SSL
|
||||
<el-tooltip
|
||||
class="item"
|
||||
effect="dark"
|
||||
:content="$t('system_parameter_setting.to_enable_ssl')"
|
||||
placement="top"
|
||||
>
|
||||
<i class="el-icon-warning-outline tips-not-absolute" />
|
||||
</el-tooltip>
|
||||
</el-checkbox>
|
||||
|
||||
<el-checkbox v-model="formInline.tls">
|
||||
{{ $t('chart.open') }}TSL
|
||||
<el-tooltip
|
||||
class="item"
|
||||
effect="dark"
|
||||
:content="$t('system_parameter_setting.to_enable_tsl')"
|
||||
placement="top"
|
||||
>
|
||||
<i class="el-icon-warning-outline tips-not-absolute" />
|
||||
</el-tooltip>
|
||||
</el-checkbox>
|
||||
</el-form-item>
|
||||
<template #footer />
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { emailInfo, updateInfo, validate } from '@/api/system/email'
|
||||
import operater from './Operater'
|
||||
import msgCfm from '@/components/msgCfm'
|
||||
import dePwd from '@/components/deCustomCm/dePwd.vue'
|
||||
export default {
|
||||
name: 'EmailSetting',
|
||||
components: {
|
||||
operater,
|
||||
dePwd
|
||||
},
|
||||
mixins: [msgCfm],
|
||||
data() {
|
||||
return {
|
||||
formInline: {},
|
||||
input: '',
|
||||
visible: true,
|
||||
showEdit: true,
|
||||
showSave: false,
|
||||
showCancel: false,
|
||||
show: true,
|
||||
disabledConnection: false,
|
||||
disabledSave: false,
|
||||
loading: false,
|
||||
rules: {
|
||||
host: [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('system_parameter_setting.host'),
|
||||
trigger: ['change', 'blur']
|
||||
}
|
||||
],
|
||||
port: [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('system_parameter_setting.port'),
|
||||
trigger: ['change', 'blur']
|
||||
}
|
||||
],
|
||||
account: [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('system_parameter_setting.account'),
|
||||
trigger: ['change', 'blur']
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.query()
|
||||
},
|
||||
methods: {
|
||||
query() {
|
||||
emailInfo().then((response) => {
|
||||
this.formInline = response.data
|
||||
this.formInline.ssl = this.formInline.ssl === 'true'
|
||||
this.formInline.tls = this.formInline.tls === 'true'
|
||||
this.$nextTick(() => {
|
||||
this.$refs.formInline.clearValidate()
|
||||
})
|
||||
})
|
||||
},
|
||||
change() {
|
||||
if (
|
||||
!this.formInline.host ||
|
||||
!this.formInline.port ||
|
||||
!this.formInline.account
|
||||
) {
|
||||
this.disabledConnection = true
|
||||
this.disabledSave = true
|
||||
} else {
|
||||
this.disabledConnection = false
|
||||
this.disabledSave = false
|
||||
}
|
||||
},
|
||||
testConnection(formInline) {
|
||||
const param = {
|
||||
'smtp.host': this.formInline.host,
|
||||
'smtp.port': this.formInline.port,
|
||||
'smtp.account': this.formInline.account,
|
||||
'smtp.password': this.formInline.password,
|
||||
'smtp.ssl': this.formInline.ssl,
|
||||
'smtp.tls': this.formInline.tls,
|
||||
'smtp.recipient': this.formInline.recipient
|
||||
}
|
||||
this.$refs[formInline].validate((valid) => {
|
||||
if (valid) {
|
||||
validate(param).then((response) => {
|
||||
this.openMessageSuccess('commons.connection_successful')
|
||||
})
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
edit() {
|
||||
this.showEdit = false
|
||||
this.showSave = true
|
||||
this.showCancel = true
|
||||
this.show = false
|
||||
},
|
||||
save(formInline) {
|
||||
this.showEdit = true
|
||||
this.showCancel = false
|
||||
this.showSave = false
|
||||
this.show = true
|
||||
const param = [
|
||||
{
|
||||
paramKey: 'smtp.host',
|
||||
paramValue: this.formInline.host,
|
||||
type: 'text',
|
||||
sort: 1
|
||||
},
|
||||
{
|
||||
paramKey: 'smtp.port',
|
||||
paramValue: this.formInline.port,
|
||||
type: 'text',
|
||||
sort: 2
|
||||
},
|
||||
{
|
||||
paramKey: 'smtp.account',
|
||||
paramValue: this.formInline.account,
|
||||
type: 'text',
|
||||
sort: 3
|
||||
},
|
||||
{
|
||||
paramKey: 'smtp.password',
|
||||
paramValue: this.formInline.password,
|
||||
type: 'password',
|
||||
sort: 4
|
||||
},
|
||||
{
|
||||
paramKey: 'smtp.ssl',
|
||||
paramValue: this.formInline.ssl,
|
||||
type: 'text',
|
||||
sort: 5
|
||||
},
|
||||
{
|
||||
paramKey: 'smtp.tls',
|
||||
paramValue: this.formInline.tls,
|
||||
type: 'text',
|
||||
sort: 6
|
||||
},
|
||||
{
|
||||
paramKey: 'smtp.recipient',
|
||||
paramValue: this.formInline.recipient,
|
||||
type: 'text',
|
||||
sort: 8
|
||||
}
|
||||
]
|
||||
|
||||
this.$refs[formInline].validate((valid) => {
|
||||
if (valid) {
|
||||
updateInfo(param).then((response) => {
|
||||
const flag = response.success
|
||||
if (flag) {
|
||||
this.openMessageSuccess('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()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
385
frontend/src/views/system/sysParam/KettleSetting.vue
Normal file
385
frontend/src/views/system/sysParam/KettleSetting.vue
Normal file
@ -0,0 +1,385 @@
|
||||
<template>
|
||||
<div class="kettle-setting">
|
||||
<deBtn
|
||||
type="primary"
|
||||
icon="el-icon-plus"
|
||||
@click="create(undefined)"
|
||||
>{{
|
||||
$t("kettle.add")
|
||||
}}</deBtn>
|
||||
<div class="table-box">
|
||||
<grid-table
|
||||
:table-data="data"
|
||||
:pagination="paginationConfig"
|
||||
@size-change="sizeChange"
|
||||
@current-change="currentChange"
|
||||
>
|
||||
<el-table-column
|
||||
prop="configuration.carte"
|
||||
:label="$t('kettle.carte')"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="configuration.port"
|
||||
:label="$t('kettle.port')"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="status"
|
||||
:label="$t('kettle.status')"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span
|
||||
v-if="scope.row.status === 'Error'"
|
||||
class="de-tag"
|
||||
style="color: #646a73; background: rgba(31, 35, 41, 0.1)"
|
||||
>{{ $t("datasource.invalid") }}</span>
|
||||
<span
|
||||
v-if="scope.row.status === 'Success'"
|
||||
class="de-tag"
|
||||
style="color: green; background: rgba(52, 199, 36, 0.2)"
|
||||
>{{ $t("datasource.valid") }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
slot="__operation"
|
||||
:label="$t('commons.operating')"
|
||||
fixed="right"
|
||||
width="168"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
class="text-btn"
|
||||
type="text"
|
||||
@click="create(scope.row)"
|
||||
>{{ $t("commons.edit") }}</el-button>
|
||||
<el-button
|
||||
class="text-btn"
|
||||
type="text"
|
||||
@click="validateById(scope.row)"
|
||||
>{{ $t("commons.validate") }}</el-button>
|
||||
<el-button
|
||||
class="text-btn"
|
||||
type="text"
|
||||
@click="del(scope.row)"
|
||||
>{{
|
||||
$t("commons.delete")
|
||||
}}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</grid-table>
|
||||
</div>
|
||||
<el-dialog
|
||||
v-dialogDrag
|
||||
:title="edit_dialog_title"
|
||||
:visible="show_dialog"
|
||||
:before-close="closeDialog"
|
||||
:show-close="true"
|
||||
width="50%"
|
||||
class="dialog-css de-kettle"
|
||||
append-to-body
|
||||
>
|
||||
<el-col>
|
||||
<el-form
|
||||
ref="kettleform"
|
||||
class="de-form-item"
|
||||
:form="form"
|
||||
:model="form"
|
||||
label-width="120px"
|
||||
:rules="rule"
|
||||
>
|
||||
<el-form-item
|
||||
:label="$t('kettle.carte')"
|
||||
prop="configuration.carte"
|
||||
>
|
||||
<el-input
|
||||
v-model="form.configuration.carte"
|
||||
:placeholder="$t('components.enter_kettle_address')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="$t('kettle.port')"
|
||||
prop="configuration.port"
|
||||
>
|
||||
<el-input-number
|
||||
v-model="form.configuration.port"
|
||||
controls-position="right"
|
||||
:placeholder="$t('components.enter_the_port')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="$t('kettle.user')"
|
||||
prop="configuration.user"
|
||||
>
|
||||
<el-input
|
||||
v-model="form.configuration.user"
|
||||
:placeholder="$t('components.one_user_name')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="$t('kettle.passwd')"
|
||||
prop="configuration.passwd"
|
||||
>
|
||||
<dePwd
|
||||
v-model="form.configuration.passwd"
|
||||
:placeholder="$t('components.input_a_password')"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-col>
|
||||
<div
|
||||
slot="footer"
|
||||
class="dialog-footer"
|
||||
>
|
||||
<deBtn
|
||||
secondary
|
||||
@click="closeDialog"
|
||||
>
|
||||
{{ $t("commons.cancel") }}
|
||||
</deBtn>
|
||||
<deBtn
|
||||
secondary
|
||||
@click="validate()"
|
||||
>{{
|
||||
$t("commons.validate")
|
||||
}}</deBtn>
|
||||
<deBtn
|
||||
type="primary"
|
||||
@click="save()"
|
||||
>{{
|
||||
$t("commons.confirm")
|
||||
}}</deBtn>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
deleteKettle,
|
||||
validate,
|
||||
save,
|
||||
pageList,
|
||||
validateById
|
||||
} from '@/api/system/kettle'
|
||||
import GridTable from '@/components/gridTable/index.vue'
|
||||
import dePwd from '@/components/deCustomCm/dePwd.vue'
|
||||
import msgCfm from '@/components/msgCfm'
|
||||
|
||||
export default {
|
||||
name: 'KettleSetting',
|
||||
components: { GridTable, dePwd },
|
||||
mixins: [msgCfm],
|
||||
data() {
|
||||
return {
|
||||
paginationConfig: {
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
total: 0
|
||||
},
|
||||
data: [],
|
||||
show_dialog: false,
|
||||
edit_dialog_title: '',
|
||||
form: {
|
||||
configuration: {
|
||||
carte: '',
|
||||
port: '',
|
||||
user: '',
|
||||
passwd: ''
|
||||
}
|
||||
},
|
||||
rule: {
|
||||
'configuration.carte': [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('components.address_is_required'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
'configuration.port': [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('components.port_is_required'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
'configuration.user': [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('components.name_is_required'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
'configuration.passwd': [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('components.password_is_required'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.search()
|
||||
},
|
||||
methods: {
|
||||
initSearch() {
|
||||
this.currentChange(1)
|
||||
},
|
||||
currentChange(currentPage) {
|
||||
this.paginationConfig.currentPage = currentPage
|
||||
this.search()
|
||||
},
|
||||
sizeChange(pageSize) {
|
||||
this.paginationConfig.pageSize = pageSize
|
||||
this.paginationConfig.currentPage = 1
|
||||
this.search()
|
||||
},
|
||||
search() {
|
||||
const { currentPage, pageSize } = this.paginationConfig
|
||||
pageList('/kettle/pageList/' + currentPage + '/' + pageSize, {}).then(
|
||||
(response) => {
|
||||
this.data = response.data.listObject
|
||||
this.data.forEach((item) => {
|
||||
item.configuration = JSON.parse(item.configuration)
|
||||
})
|
||||
this.paginationConfig.total = response.data.itemCount
|
||||
}
|
||||
)
|
||||
},
|
||||
del(item) {
|
||||
deleteKettle(item.id).then((response) => {
|
||||
this.initSearch()
|
||||
})
|
||||
},
|
||||
create(item) {
|
||||
if (!item) {
|
||||
this.targetObjs = []
|
||||
this.form = {
|
||||
configuration: { carte: '', port: '', user: '', passwd: '' }
|
||||
}
|
||||
this.edit_dialog_title = this.$t('kettle.add')
|
||||
} else {
|
||||
this.edit_dialog_title = this.$t('commons.edit')
|
||||
this.form = JSON.parse(JSON.stringify(item))
|
||||
}
|
||||
this.show_dialog = true
|
||||
},
|
||||
|
||||
save() {
|
||||
this.$refs.kettleform.validate((valid) => {
|
||||
if (!valid) {
|
||||
return false
|
||||
}
|
||||
const form = JSON.parse(JSON.stringify(this.form))
|
||||
form.configuration = JSON.stringify(form.configuration)
|
||||
save(form).then((res) => {
|
||||
this.show_dialog = false
|
||||
this.openMessageSuccess('commons.save_success')
|
||||
this.initSearch()
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
closeDialog() {
|
||||
this.$refs.kettleform.resetFields()
|
||||
this.show_dialog = false
|
||||
this.form = {
|
||||
configuration: { carte: '', port: '', user: '', passwd: '' }
|
||||
}
|
||||
},
|
||||
|
||||
validate() {
|
||||
this.$refs.kettleform.validate((valid) => {
|
||||
if (valid) {
|
||||
validate(this.form.configuration)
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
this.openMessageSuccess('datasource.validate_success')
|
||||
} else {
|
||||
if (res.message.length < 2500) {
|
||||
this.$error(res.message)
|
||||
} else {
|
||||
this.$error(res.message.substring(0, 2500) + '......')
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((res) => {
|
||||
this.$error(res.message)
|
||||
})
|
||||
} else {
|
||||
return
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
validateById(item) {
|
||||
validateById(item.id)
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
item.status = res.data.status
|
||||
this.openMessageSuccess('datasource.validate_success')
|
||||
} else {
|
||||
item.status = 'Error'
|
||||
if (res.message.length < 2500) {
|
||||
this.$error(res.message)
|
||||
} else {
|
||||
this.$error(res.message.substring(0, 2500) + '......')
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((res) => {
|
||||
this.$error(res.message)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.kettle-setting {
|
||||
height: 100%;
|
||||
.table-box {
|
||||
height: calc(100% - 52px);
|
||||
margin-top: 16px;
|
||||
|
||||
.text-btn {
|
||||
font-family: PingFang SC;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 22px;
|
||||
letter-spacing: 0px;
|
||||
text-align: center;
|
||||
margin-left: 2px;
|
||||
border: none;
|
||||
padding: 2px 4px;
|
||||
}
|
||||
|
||||
.text-btn:hover {
|
||||
background: rgba(51, 112, 255, 0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style lang="scss">
|
||||
.de-kettle {
|
||||
.el-input-number {
|
||||
width: 100%;
|
||||
.el-input__inner {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.el-input-number__decrease,
|
||||
.el-input-number__increase {
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
.de-tag {
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 2px;
|
||||
padding: 1px 6px;
|
||||
height: 24px;
|
||||
}
|
||||
</style>
|
284
frontend/src/views/system/sysParam/MapSetting/MapSettingLeft.vue
Normal file
284
frontend/src/views/system/sysParam/MapSetting/MapSettingLeft.vue
Normal file
@ -0,0 +1,284 @@
|
||||
<template>
|
||||
<el-col class="tree-style">
|
||||
<el-col>
|
||||
|
||||
<el-row style="margin-bottom: 10px">
|
||||
<el-input
|
||||
v-model="filterText"
|
||||
size="small"
|
||||
:placeholder="$t('commons.search')"
|
||||
prefix-icon="el-icon-search"
|
||||
clearable
|
||||
class="main-area-input"
|
||||
/>
|
||||
|
||||
</el-row>
|
||||
|
||||
<el-col class="custom-tree-container">
|
||||
<div class="block">
|
||||
<el-tree
|
||||
ref="tree"
|
||||
class="filter-tree"
|
||||
:data="treeDatas"
|
||||
:props="defaultProps"
|
||||
:filter-node-method="filterNode"
|
||||
:expand-on-click-node="false"
|
||||
node-key="code"
|
||||
:accordion="true"
|
||||
highlight-current
|
||||
:default-expanded-keys="expandedKeys"
|
||||
@current-change="nodeClick"
|
||||
>
|
||||
<span
|
||||
slot-scope="{ node, data }"
|
||||
class="custom-tree-node father"
|
||||
>
|
||||
<span style="display: flex;flex: 1;width: 0;">
|
||||
|
||||
<span
|
||||
style="margin-left: 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;"
|
||||
:title="data.name"
|
||||
>{{ node.data.name }}</span>
|
||||
</span>
|
||||
<span
|
||||
v-if="!isChina(data.code)"
|
||||
class="child"
|
||||
>
|
||||
<span @click.stop>
|
||||
<span class="el-dropdown-link">
|
||||
<el-button
|
||||
icon="el-icon-plus"
|
||||
type="text"
|
||||
size="small"
|
||||
@click="addHandler(data, node)"
|
||||
/>
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
v-if="!isGlobal(data.code)"
|
||||
style="margin-left: 12px;"
|
||||
@click.stop
|
||||
>
|
||||
<span class="el-dropdown-link">
|
||||
<el-button
|
||||
icon="el-icon-delete"
|
||||
type="text"
|
||||
size="small"
|
||||
@click="removeHandler(data, node)"
|
||||
/>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</el-tree>
|
||||
</div>
|
||||
|
||||
</el-col>
|
||||
|
||||
</el-col>
|
||||
|
||||
</el-col>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { removeMap } from '@/api/map/map'
|
||||
import msgCfm from '@/components/msgCfm'
|
||||
export default {
|
||||
name: 'MapSettingLeft',
|
||||
mixins: [msgCfm],
|
||||
props: {
|
||||
treeDatas: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
filterText: '',
|
||||
defaultProps: {
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
value: 'id'
|
||||
},
|
||||
expandedKeys: []
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
filterText(val) {
|
||||
this.$refs.tree.filter(val)
|
||||
}
|
||||
},
|
||||
created() {
|
||||
},
|
||||
methods: {
|
||||
|
||||
filterNode(value, data) {
|
||||
if (!value) return true
|
||||
return data.name.indexOf(value) !== -1
|
||||
},
|
||||
|
||||
nodeClick(data, node) {
|
||||
let parent = null
|
||||
if (node.parent.data instanceof Array) {
|
||||
parent = node.parent.data[0]
|
||||
} else {
|
||||
parent = node.parent.data
|
||||
}
|
||||
const nodeInfo = {
|
||||
code: data.code,
|
||||
name: data.name,
|
||||
pcode: data.pcode,
|
||||
pname: parent.name
|
||||
}
|
||||
this.$emit('show-node-info', this.setStatus(nodeInfo, 'read-only'))
|
||||
},
|
||||
addHandler(data, node) {
|
||||
let form = {
|
||||
pLevel: node.level,
|
||||
pCode: data.code
|
||||
}
|
||||
if (node.level > 4) {
|
||||
this.$error('不支持4级行政级别')
|
||||
form = {}
|
||||
}
|
||||
this.$emit('emit-add', this.setStatus(form, 'add'))
|
||||
},
|
||||
removeHandler(data, node) {
|
||||
let parent = null
|
||||
if (node.parent.data instanceof Array) {
|
||||
parent = node.parent.data[0]
|
||||
} else {
|
||||
parent = node.parent.data
|
||||
}
|
||||
const param = {
|
||||
code: data.code,
|
||||
pcode: parent.code,
|
||||
plevel: node.parent.level,
|
||||
name: data.name
|
||||
}
|
||||
const msg = this.$t('map_setting.cur_node') + '[' + data.name + ']' + this.$t('map_setting.delete_confirm')
|
||||
this.$confirm(msg, '', {
|
||||
confirmButtonText: this.$t('commons.confirm'),
|
||||
cancelButtonText: this.$t('commons.cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
removeMap(param).then(res => {
|
||||
this.$store.dispatch('map/setGeo', {
|
||||
key: param.code,
|
||||
value: null
|
||||
}).then(() => {
|
||||
this.$emit('refresh-tree')
|
||||
this.openMessageSuccess('commons.delete_success')
|
||||
})
|
||||
})
|
||||
}).catch(() => {
|
||||
this.$info(this.$t('commons.delete_cancel'))
|
||||
})
|
||||
},
|
||||
setStatus(data, status) {
|
||||
const form = JSON.parse(JSON.stringify(data))
|
||||
return Object.assign(form, {
|
||||
status: status || 'read-only'
|
||||
})
|
||||
},
|
||||
showNewNode(code) {
|
||||
this.$refs.tree.setCurrentKey(code)
|
||||
},
|
||||
isChina(code) {
|
||||
return code && code.startsWith('156')
|
||||
},
|
||||
isGlobal(code) {
|
||||
return code && code.startsWith('000')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.el-divider--horizontal {
|
||||
margin: 12px 0
|
||||
}
|
||||
|
||||
.search-input {
|
||||
padding: 12px 0;
|
||||
}
|
||||
|
||||
.custom-tree-container{
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.tree-list ::v-deep .el-tree-node__expand-icon.is-leaf{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.custom-tree-node {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-size: 14px;
|
||||
padding-right:8px;
|
||||
}
|
||||
|
||||
.custom-tree-node-list {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-size: 14px;
|
||||
padding:0 8px;
|
||||
}
|
||||
|
||||
.custom-position {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
flex-flow: row nowrap;
|
||||
}
|
||||
|
||||
.form-item {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.title-css {
|
||||
height: 26px;
|
||||
}
|
||||
|
||||
.title-text {
|
||||
line-height: 26px;
|
||||
}
|
||||
|
||||
.scene-title{
|
||||
width: 100%;
|
||||
display: flex;
|
||||
}
|
||||
.scene-title-name{
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.father .child {
|
||||
visibility: hidden;
|
||||
}
|
||||
.father:hover .child {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.dialog-css ::v-deep .el-dialog__body {
|
||||
padding: 10px 20px 20px;
|
||||
}
|
||||
|
||||
.inner-dropdown-menu{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 100%
|
||||
}
|
||||
.tree-style {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,385 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--基础配置表单-->
|
||||
<el-form
|
||||
v-if="status !== 'empty' && status !== 'read-only'"
|
||||
ref="formInline"
|
||||
v-loading="loading"
|
||||
:model="formInline"
|
||||
:rules="rules"
|
||||
class="demo-form-inline"
|
||||
size="small"
|
||||
>
|
||||
<el-input
|
||||
v-show="false"
|
||||
v-model="formInline.pLevel"
|
||||
/>
|
||||
|
||||
<el-row>
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form-item
|
||||
:label="$t('map_setting.parent_area')"
|
||||
prop="pCode"
|
||||
>
|
||||
<el-tree-select
|
||||
v-if="treeShow"
|
||||
ref="deSelectTree"
|
||||
v-model="formInline.pCode"
|
||||
:popper-append-to-body="true"
|
||||
popover-class="map-class-wrap"
|
||||
:data="treeDatas"
|
||||
:select-params="selectParams"
|
||||
:tree-params="treeParams"
|
||||
:filter-node-method="_filterFun"
|
||||
:tree-render-fun="_renderFun"
|
||||
@searchFun="_searchFun"
|
||||
@node-click="changeNode"
|
||||
@select-clear="selectClear"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form-item
|
||||
:label="$t('map_setting.area_code')"
|
||||
prop="code"
|
||||
>
|
||||
<el-input
|
||||
v-model="formInline.code"
|
||||
:placeholder="$t('map_setting.please_input')"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form-item
|
||||
:label="$t('map_setting.area_name')"
|
||||
prop="name"
|
||||
>
|
||||
<el-input
|
||||
v-model="formInline.name"
|
||||
maxlength="30"
|
||||
show-word-limit
|
||||
:placeholder="$t('map_setting.please_input')"
|
||||
/>
|
||||
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form-item :label="$t('map_setting.geo_json')">
|
||||
<el-upload
|
||||
style="float: right;margin-left: 10px"
|
||||
class="upload-demo"
|
||||
action=""
|
||||
accept=".json"
|
||||
:on-exceed="handleExceed"
|
||||
:before-upload="uploadValidate"
|
||||
:on-error="handleError"
|
||||
:show-file-list="false"
|
||||
:file-list="filesTmp"
|
||||
:http-request="uploadMapFile"
|
||||
>
|
||||
<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="removeFile"
|
||||
>
|
||||
{{ $t('commons.clear') }}
|
||||
</el-button>
|
||||
<el-input
|
||||
v-model="formInline.fileName"
|
||||
:disabled="true"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div>
|
||||
|
||||
<el-button
|
||||
type="success"
|
||||
size="small"
|
||||
@click="save('formInline')"
|
||||
>
|
||||
{{ $t('commons.save') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
|
||||
<el-descriptions
|
||||
v-else-if="status === 'read-only'"
|
||||
title="区域信息"
|
||||
:column="1"
|
||||
>
|
||||
|
||||
<el-descriptions-item :label="$t('map_setting.area_code')">{{ nodeInfo.code }}</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item :label="$t('map_setting.area_name')">{{ nodeInfo.name }}</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item :label="$t('map_setting.parent_name')">{{ nodeInfo.pname }}</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item :label="$t('map_setting.geo_json')">
|
||||
<json-view :data="json" />
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
|
||||
<el-empty
|
||||
v-else-if="status === 'empty'"
|
||||
description="请在左侧选择区域"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import jsonView from 'vue-json-views'
|
||||
import { geoJson, saveMap } from '@/api/map/map'
|
||||
import ElTreeSelect from '@/components/ElTreeSelect'
|
||||
import msgCfm from '@/components/msgCfm'
|
||||
|
||||
export default {
|
||||
name: 'MapSettingRight',
|
||||
components: { jsonView, ElTreeSelect },
|
||||
mixins: [msgCfm],
|
||||
props: {
|
||||
status: {
|
||||
type: String,
|
||||
default: 'empty'
|
||||
},
|
||||
treeDatas: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
formInline: { pCode: '', fileName: '' },
|
||||
loading: false,
|
||||
rules: {
|
||||
pCode: [
|
||||
{ required: true, message: this.$t('map_setting.parent_name') + this.$t('commons.cannot_be_null'), trigger: 'change' }
|
||||
],
|
||||
code: [
|
||||
{ required: true, message: this.$t('map_setting.area_code') + this.$t('commons.cannot_be_null'), trigger: ['change', 'blur'] },
|
||||
{ pattern: /^\d{9}$/, message: this.$t('map_setting.area_code_tip'), trigger: ['change', 'blur'] }
|
||||
],
|
||||
name: [
|
||||
{ required: true, message: this.$t('map_setting.area_name') + this.$t('commons.cannot_be_null'), trigger: ['change', 'blur'] }
|
||||
],
|
||||
fileName: [
|
||||
{ required: true, message: this.$t('map_setting.geo_json') + this.$t('commons.cannot_be_null'), trigger: 'change' }
|
||||
]
|
||||
},
|
||||
levelOptions: [
|
||||
{ value: 1, label: '国家' },
|
||||
{ value: 2, label: '一级行政区划(省)' },
|
||||
{ value: 3, label: '二级行政区划(市)' },
|
||||
{ value: 4, label: '三级行政区划(区县)' },
|
||||
{ value: 5, label: '四级行政区划(乡镇)' }
|
||||
],
|
||||
suffixes: new Set(['json']),
|
||||
errList: [],
|
||||
filesTmp: [],
|
||||
|
||||
nodeInfo: {
|
||||
code: -1,
|
||||
name: '',
|
||||
level: -1,
|
||||
pcode: -1,
|
||||
pname: ''
|
||||
},
|
||||
noGsoJson: { success: false, message: 'no json file' },
|
||||
json: {},
|
||||
selectParams: {
|
||||
clearable: true,
|
||||
placeholder: this.$t('commons.please_select') + this.$t('map_setting.parent_name')
|
||||
},
|
||||
treeParams: {
|
||||
showParent: true,
|
||||
clickParent: true,
|
||||
filterable: true,
|
||||
// 只想要子节点,不需要父节点
|
||||
leafOnly: false,
|
||||
includeHalfChecked: false,
|
||||
'check-strictly': false,
|
||||
'default-expand-all': false,
|
||||
'expand-on-click-node': false,
|
||||
'render-content': this._renderFun,
|
||||
data: [],
|
||||
props: {
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
rootId: '000000000',
|
||||
disabled: 'disabled',
|
||||
parentId: 'pcode',
|
||||
value: 'code'
|
||||
}
|
||||
},
|
||||
treeShow: true
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
treeDatas: function(val) {
|
||||
this.treeParams.data = val
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
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 > 30) {
|
||||
this.$warning(this.$t('test_track.case.import.upload_limit_size'))
|
||||
return false
|
||||
}
|
||||
this.errList = []
|
||||
return true
|
||||
},
|
||||
uploadMapFile(file) {
|
||||
this.$set(this.formInline, 'fileName', file.file.name)
|
||||
this.formInline.file = file.file
|
||||
},
|
||||
removeFile() {
|
||||
this.formInline.fileName = null
|
||||
this.formInline.file = null
|
||||
},
|
||||
buildFormData(file, files, param) {
|
||||
const formData = new FormData()
|
||||
if (file) {
|
||||
formData.append('file', file)
|
||||
}
|
||||
if (files) {
|
||||
files.forEach(f => {
|
||||
formData.append('files', f)
|
||||
})
|
||||
}
|
||||
formData.append('request', new Blob([JSON.stringify(param)], { type: 'application/json' }))
|
||||
return formData
|
||||
},
|
||||
save(formInline) {
|
||||
const param = {
|
||||
code: this.formInline.code,
|
||||
name: this.formInline.name,
|
||||
pcode: this.formInline.pCode,
|
||||
plevel: this.formInline.pLevel
|
||||
}
|
||||
|
||||
this.$refs[formInline].validate(valid => {
|
||||
if (valid) {
|
||||
this.saveHandler(param)
|
||||
}
|
||||
})
|
||||
},
|
||||
saveHandler(param) {
|
||||
const formData = this.buildFormData(this.formInline.file, null, param)
|
||||
saveMap(formData).then(response => {
|
||||
const flag = response.success
|
||||
if (flag) {
|
||||
this.$emit('refresh-tree', param)
|
||||
this.openMessageSuccess('commons.save_success')
|
||||
} else {
|
||||
this.$message.error(this.$t('commons.save_failed'))
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
emitAdd(form) {
|
||||
this.formInline = JSON.parse(JSON.stringify(form))
|
||||
this.treeShow = false
|
||||
this.$nextTick(() => {
|
||||
this.treeShow = true
|
||||
})
|
||||
},
|
||||
|
||||
loadForm(form) {
|
||||
if (form && form.code) {
|
||||
this.nodeInfo = JSON.parse(JSON.stringify(form))
|
||||
this.setGeoJson()
|
||||
}
|
||||
},
|
||||
setGeoJson() {
|
||||
if (!this.nodeInfo || !this.nodeInfo.code) {
|
||||
this.json = JSON.parse(JSON.stringify(this.noGsoJson))
|
||||
return
|
||||
}
|
||||
const cCode = this.nodeInfo.code
|
||||
if (this.$store.getters.geoMap[cCode]) {
|
||||
const json = this.$store.getters.geoMap[cCode]
|
||||
this.json = JSON.parse(JSON.stringify(json))
|
||||
return
|
||||
}
|
||||
|
||||
geoJson(cCode).then(res => {
|
||||
this.$store.dispatch('map/setGeo', {
|
||||
key: cCode,
|
||||
value: res
|
||||
}).then(() => {
|
||||
this.json = JSON.parse(JSON.stringify(res))
|
||||
})
|
||||
})
|
||||
},
|
||||
_filterFun(value, data, node) {
|
||||
if (!value) return true
|
||||
return data.id.toString().indexOf(value.toString()) !== -1
|
||||
},
|
||||
// 树点击
|
||||
_nodeClickFun(data, node, vm) {
|
||||
},
|
||||
// 树过滤
|
||||
_searchFun(value) {
|
||||
this.$refs.deSelectTree.filterFun(value)
|
||||
},
|
||||
// 自定义render
|
||||
_renderFun(h, { node, data, store }) {
|
||||
const { props, clickParent } = this.treeParams
|
||||
return (
|
||||
<span class={['custom-tree-node', !clickParent && data[props.children] && data[props.children].length ? 'disabled' : null]}>
|
||||
<span>{node.label}</span>
|
||||
</span>
|
||||
)
|
||||
},
|
||||
changeNode(data, node) {
|
||||
if (node.level > 4) {
|
||||
this.$error('不支持4级行政级别')
|
||||
this.formInline.pLevel = null
|
||||
this.formInline.pCode = null
|
||||
return
|
||||
}
|
||||
this.formInline.pLevel = node.level
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.map-class-wrap{
|
||||
top: 65px !important;
|
||||
left: 0px !important;
|
||||
}
|
||||
</style>
|
88
frontend/src/views/system/sysParam/MapSetting/index.vue
Normal file
88
frontend/src/views/system/sysParam/MapSetting/index.vue
Normal file
@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<de-container
|
||||
v-loading="$store.getters.loadingMap[$store.getters.currentPath]"
|
||||
class="de-earth"
|
||||
style="height: calc(100vh - 150px);"
|
||||
>
|
||||
|
||||
<de-aside-container
|
||||
type="mapset"
|
||||
style="height: 100%;"
|
||||
>
|
||||
<map-setting-left
|
||||
ref="map_setting_tree"
|
||||
:tree-datas="treeDatas"
|
||||
@emit-add="emitAdd"
|
||||
@refresh-tree="refreshTree"
|
||||
@show-node-info="loadForm"
|
||||
/>
|
||||
</de-aside-container>
|
||||
|
||||
<de-main-container style="height: 100%;">
|
||||
<map-setting-right
|
||||
ref="map_setting_form"
|
||||
:tree-datas="treeDatas"
|
||||
:status="formStatus"
|
||||
@refresh-tree="refreshTree"
|
||||
/>
|
||||
</de-main-container>
|
||||
</de-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DeMainContainer from '@/components/dataease/DeMainContainer'
|
||||
import DeContainer from '@/components/dataease/DeContainer'
|
||||
import DeAsideContainer from '@/components/dataease/DeAsideContainer'
|
||||
import { areaMapping } from '@/api/map/map'
|
||||
import MapSettingLeft from './MapSettingLeft'
|
||||
import MapSettingRight from './MapSettingRight'
|
||||
export default {
|
||||
name: 'MapSetting',
|
||||
components: { DeMainContainer, DeContainer, DeAsideContainer, MapSettingLeft, MapSettingRight },
|
||||
data() {
|
||||
return {
|
||||
formStatus: 'empty',
|
||||
treeDatas: []
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.loadTreeData()
|
||||
},
|
||||
methods: {
|
||||
emitAdd(form) {
|
||||
this.setStatus(form.status)
|
||||
this.$refs && this.$refs['map_setting_form'] && this.$refs['map_setting_form'].emitAdd(form)
|
||||
},
|
||||
|
||||
loadForm(nodeInfo) {
|
||||
this.setStatus(nodeInfo.status)
|
||||
this.$refs && this.$refs['map_setting_form'] && this.$refs['map_setting_form'].loadForm(nodeInfo)
|
||||
},
|
||||
|
||||
setStatus(status) {
|
||||
this.formStatus = status
|
||||
},
|
||||
loadTreeData() {
|
||||
Object.keys(this.treeDatas).length === 0 && areaMapping().then(res => {
|
||||
this.treeDatas = res.data
|
||||
})
|
||||
},
|
||||
refreshTree(node) {
|
||||
areaMapping().then(res => {
|
||||
this.treeDatas = res.data
|
||||
if (node && node.code) {
|
||||
this.$refs && this.$refs['map_setting_tree'] && this.$refs['map_setting_tree'].showNewNode(node.code)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.de-earth {
|
||||
padding: 24px;
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
36
frontend/src/views/system/sysParam/Operater.vue
Normal file
36
frontend/src/views/system/sysParam/Operater.vue
Normal file
@ -0,0 +1,36 @@
|
||||
<template>
|
||||
<div class="operater-bar">
|
||||
<p class="title">{{ $t(title) }}</p>
|
||||
<div class="btn-grounp">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.operater-bar {
|
||||
width: 100%;
|
||||
height: 70px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
.title {
|
||||
font-family: PingFang SC;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
line-height: 24px;
|
||||
color: #1f2329;
|
||||
}
|
||||
}
|
||||
</style>
|
299
frontend/src/views/system/sysParam/SimpleModeSetting.vue
Normal file
299
frontend/src/views/system/sysParam/SimpleModeSetting.vue
Normal file
@ -0,0 +1,299 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-form
|
||||
ref="form"
|
||||
v-loading="loading"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
class="demo-form-inline"
|
||||
:disabled="show"
|
||||
label-width="180px"
|
||||
label-position="top"
|
||||
size="small"
|
||||
>
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form-item
|
||||
:label="$t('datasource.type')"
|
||||
prop="type"
|
||||
>
|
||||
<el-select
|
||||
v-model="form.type"
|
||||
:placeholder="$t('datasource.please_choose_type')"
|
||||
|
||||
filterable
|
||||
@change="changeType()"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in allTypes"
|
||||
:key="item.name"
|
||||
:label="item.label"
|
||||
:value="item.name"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form-item
|
||||
:label="$t('datasource.host')"
|
||||
prop="configuration.host"
|
||||
>
|
||||
<el-input v-model="form.configuration.host" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form-item
|
||||
:label="$t('datasource.data_base')"
|
||||
prop="configuration.dataBase"
|
||||
>
|
||||
<el-input v-model="form.configuration.dataBase" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form-item :label="$t('datasource.user_name')">
|
||||
<el-input v-model="form.configuration.username" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form-item :label="$t('datasource.password')">
|
||||
<el-input
|
||||
v-model="form.configuration.password"
|
||||
show-password
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form-item
|
||||
:label="$t('datasource.port')"
|
||||
prop="configuration.port"
|
||||
>
|
||||
<el-input
|
||||
v-model="form.configuration.port"
|
||||
autocomplete="off"
|
||||
type="number"
|
||||
min="0"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form-item :label="$t('datasource.extra_params')">
|
||||
<el-input v-model="form.configuration.extraParams" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<div>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="validaDatasource"
|
||||
>
|
||||
{{ $t('commons.validate') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="showEdit"
|
||||
size="small"
|
||||
@click="edit"
|
||||
>
|
||||
{{ $t('commons.edit') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="showSave"
|
||||
type="success"
|
||||
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 { engineInfo, validate, save } from '@/api/system/engine'
|
||||
import i18n from '@/lang'
|
||||
import msgCfm from '@/components/msgCfm'
|
||||
|
||||
export default {
|
||||
name: 'SimpleMode',
|
||||
mixins: [msgCfm],
|
||||
data() {
|
||||
return {
|
||||
form:
|
||||
{
|
||||
type: 'engine_mysql',
|
||||
configuration: {
|
||||
host: '',
|
||||
dataBase: '',
|
||||
username: '',
|
||||
password: '',
|
||||
port: '',
|
||||
extraParams: 'characterEncoding=UTF-8&connectTimeout=5000&useSSL=false&allowPublicKeyRetrieval=true&zeroDateTimeBehavior=convertToNull'
|
||||
}
|
||||
},
|
||||
originConfiguration: {
|
||||
host: '',
|
||||
dataBase: '',
|
||||
username: '',
|
||||
password: '',
|
||||
port: '',
|
||||
extraParams: 'characterEncoding=UTF-8&connectTimeout=5000&useSSL=false&allowPublicKeyRetrieval=true&zeroDateTimeBehavior=convertToNull'
|
||||
},
|
||||
input: '',
|
||||
visible: true,
|
||||
showEdit: true,
|
||||
showSave: false,
|
||||
showCancel: false,
|
||||
show: true,
|
||||
disabledConnection: false,
|
||||
disabledSave: false,
|
||||
loading: false,
|
||||
rules: {
|
||||
'configuration.host': [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('datasource.please_input_host'),
|
||||
trigger: ['change', 'blur']
|
||||
}
|
||||
],
|
||||
'configuration.port': [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('datasource.please_input_port'),
|
||||
trigger: ['change', 'blur']
|
||||
}
|
||||
],
|
||||
'configuration.dataBase': [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('datasource.please_input_data_base'),
|
||||
trigger: ['change', 'blur']
|
||||
}
|
||||
]
|
||||
},
|
||||
allTypes: [
|
||||
{
|
||||
name: 'engine_mysql',
|
||||
label: 'MySQL',
|
||||
type: 'jdbc',
|
||||
extraParams: 'characterEncoding=UTF-8&connectTimeout=5000&useSSL=false&allowPublicKeyRetrieval=true'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.query()
|
||||
},
|
||||
methods: {
|
||||
query() {
|
||||
engineInfo().then(response => {
|
||||
if (response.data.id) {
|
||||
this.form = JSON.parse(JSON.stringify(response.data))
|
||||
this.form.configuration = JSON.parse(this.form.configuration)
|
||||
this.originConfiguration = JSON.parse(JSON.stringify(this.form.configuration))
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
this.$refs.form.clearValidate()
|
||||
})
|
||||
})
|
||||
},
|
||||
edit() {
|
||||
this.showEdit = false
|
||||
this.showSave = true
|
||||
this.showCancel = true
|
||||
this.show = false
|
||||
},
|
||||
save() {
|
||||
if (this.form.configuration.dataSourceType === 'jdbc' && this.form.configuration.port <= 0) {
|
||||
this.$message.error(i18n.t('datasource.port_no_less_then_0'))
|
||||
return
|
||||
}
|
||||
if (this.form.configuration.initialPoolSize < 0 || this.form.configuration.minPoolSize < 0 || this.form.configuration.maxPoolSize < 0) {
|
||||
this.$message.error(i18n.t('datasource.no_less_then_0'))
|
||||
return
|
||||
}
|
||||
this.$refs.form.validate(valid => {
|
||||
if (!valid) {
|
||||
return false
|
||||
}
|
||||
const form = JSON.parse(JSON.stringify(this.form))
|
||||
form.configuration = JSON.stringify(form.configuration)
|
||||
save(form).then(res => {
|
||||
this.showEdit = true
|
||||
this.showCancel = false
|
||||
this.showSave = false
|
||||
this.show = true
|
||||
this.originConfiguration = JSON.parse(JSON.stringify(this.form.configuration))
|
||||
this.openMessageSuccess('commons.save_success')
|
||||
})
|
||||
})
|
||||
},
|
||||
cancel() {
|
||||
this.showEdit = true
|
||||
this.showCancel = false
|
||||
this.showSave = false
|
||||
this.show = true
|
||||
this.form.configuration = JSON.parse(JSON.stringify(this.originConfiguration))
|
||||
},
|
||||
changeType() {
|
||||
for (let i = 0; i < this.allTypes.length; i++) {
|
||||
if (this.allTypes[i].name === this.form.type) {
|
||||
this.form.configuration.dataSourceType = this.allTypes[i].type
|
||||
this.form.configuration.extraParams = this.allTypes[i].extraParams
|
||||
}
|
||||
}
|
||||
},
|
||||
validaDatasource() {
|
||||
if (!this.form.configuration.schema && this.form.type === 'oracle') {
|
||||
this.$message.error(i18n.t('datasource.please_choose_schema'))
|
||||
return
|
||||
}
|
||||
if (this.form.configuration.dataSourceType === 'jdbc' && this.form.configuration.port <= 0) {
|
||||
this.$message.error(i18n.t('datasource.port_no_less_then_0'))
|
||||
return
|
||||
}
|
||||
this.$refs.form.validate(valid => {
|
||||
if (valid) {
|
||||
const data = JSON.parse(JSON.stringify(this.form))
|
||||
data.configuration = JSON.stringify(data.configuration)
|
||||
validate(data).then(res => {
|
||||
if (res.success) {
|
||||
this.openMessageSuccess('datasource.validate_success')
|
||||
} else {
|
||||
if (res.message.length < 2500) {
|
||||
this.$error(res.message)
|
||||
} else {
|
||||
this.$error(res.message.substring(0, 2500) + '......')
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
145
frontend/src/views/system/sysParam/index.vue
Normal file
145
frontend/src/views/system/sysParam/index.vue
Normal file
@ -0,0 +1,145 @@
|
||||
<template>
|
||||
<de-layout-content
|
||||
v-loading="$store.getters.loadingMap[$store.getters.currentPath]"
|
||||
>
|
||||
<div class="sys-setting">
|
||||
<el-tabs
|
||||
v-model="activeName"
|
||||
class="de-tabs"
|
||||
>
|
||||
<el-tab-pane
|
||||
:lazy="true"
|
||||
:label="$t('system_parameter_setting.basic_setting')"
|
||||
name="zero"
|
||||
/>
|
||||
|
||||
<el-tab-pane
|
||||
:lazy="true"
|
||||
:label="$t('system_parameter_setting.mailbox_service_settings')"
|
||||
name="first"
|
||||
/>
|
||||
|
||||
<el-tab-pane
|
||||
:lazy="true"
|
||||
:label="$t('sysParams.map')"
|
||||
name="ten"
|
||||
/>
|
||||
|
||||
<el-tab-pane
|
||||
v-if="engineMode === 'simple'"
|
||||
:lazy="true"
|
||||
:label="$t('system_parameter_setting.engine_mode_setting')"
|
||||
name="six"
|
||||
/>
|
||||
|
||||
<el-tab-pane
|
||||
v-if="engineMode === 'cluster'"
|
||||
:lazy="true"
|
||||
:label="$t('system_parameter_setting.engine_mode_setting')"
|
||||
name="seven"
|
||||
/>
|
||||
|
||||
<el-tab-pane
|
||||
v-if="engineMode === 'cluster'"
|
||||
:lazy="true"
|
||||
:label="$t('system_parameter_setting.kettle_setting')"
|
||||
name="eight"
|
||||
/>
|
||||
</el-tabs>
|
||||
<div
|
||||
class="tabs-container"
|
||||
:class="[activeName !== 'eight' ? 'is-center' : 'pad-center']"
|
||||
>
|
||||
<div class="min-w600">
|
||||
<basic-setting
|
||||
v-if="activeName === 'zero'"
|
||||
:is-plugin-loaded="isPluginLoaded"
|
||||
/>
|
||||
<email-setting v-if="activeName === 'first'" />
|
||||
<map-setting
|
||||
v-if="activeName === 'ten'"
|
||||
ref="mapSetting"
|
||||
/>
|
||||
<simple-mode v-if="activeName === 'six'" />
|
||||
<cluster-mode v-if="activeName === 'seven'" />
|
||||
<kettle-setting v-if="activeName === 'eight'" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</de-layout-content>
|
||||
</template>
|
||||
<script>
|
||||
import BasicSetting from './BasicSetting'
|
||||
import MapSetting from './MapSetting'
|
||||
import EmailSetting from './EmailSetting'
|
||||
import SimpleMode from './SimpleModeSetting'
|
||||
import ClusterMode from './ClusterModeSetting'
|
||||
import KettleSetting from './KettleSetting'
|
||||
import DeLayoutContent from '@/components/business/DeLayoutContent'
|
||||
import { pluginLoaded } from '@/api/user'
|
||||
import { engineMode } from '@/api/system/engine'
|
||||
export default {
|
||||
components: {
|
||||
BasicSetting,
|
||||
EmailSetting,
|
||||
DeLayoutContent,
|
||||
SimpleMode,
|
||||
ClusterMode,
|
||||
KettleSetting,
|
||||
MapSetting
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activeName: 'zero',
|
||||
isPluginLoaded: false,
|
||||
engineMode: 'local'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
beforeCreate() {
|
||||
pluginLoaded().then((res) => {
|
||||
this.isPluginLoaded = res.success && res.data
|
||||
})
|
||||
engineMode().then((res) => {
|
||||
this.engineMode = res.data
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
handlerBtn(btn) {
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.sys-setting {
|
||||
height: 100%;
|
||||
background-color: var(--MainBG, #f5f6f7);
|
||||
|
||||
.tabs-container {
|
||||
height: calc(100% - 48px);
|
||||
background: var(--ContentBG, #ffffff);
|
||||
overflow-x: auto;
|
||||
|
||||
.min-w600 {
|
||||
min-width: 600px;
|
||||
height: 100%;
|
||||
& > :nth-child(1) {
|
||||
box-sizing: border-box;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.is-center {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 0 20px 20px 20px;
|
||||
}
|
||||
|
||||
.pad-center {
|
||||
padding: 24px;
|
||||
}
|
||||
}
|
||||
</style>
|
143
frontend/src/views/system/task/Dataset.vue
Normal file
143
frontend/src/views/system/task/Dataset.vue
Normal file
@ -0,0 +1,143 @@
|
||||
<template>
|
||||
<de-layout-content>
|
||||
<div class="de-task-record">
|
||||
<el-tabs
|
||||
v-model="tabActive"
|
||||
@tab-click="changeTab"
|
||||
>
|
||||
<el-tab-pane
|
||||
:label="$t('dataset.task.list')"
|
||||
name="DatasetTaskList"
|
||||
/>
|
||||
<el-tab-pane
|
||||
:label="$t('dataset.task.record')"
|
||||
name="TaskRecord"
|
||||
/>
|
||||
</el-tabs>
|
||||
<div class="tabs-container">
|
||||
<dataset-task-list
|
||||
v-if="tabActive == 'DatasetTaskList'"
|
||||
:param="task"
|
||||
:trans-condition="transCondition"
|
||||
@jumpTaskRecord="jumpTaskRecord"
|
||||
/>
|
||||
<task-record
|
||||
v-if="tabActive == 'TaskRecord'"
|
||||
ref="task_record"
|
||||
:param="task"
|
||||
:trans-condition="transCondition"
|
||||
@jumpTask="jumpTask"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</de-layout-content>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DeLayoutContent from '@/components/business/DeLayoutContent'
|
||||
|
||||
import DatasetTaskList from '@/views/system/task/DatasetTaskList'
|
||||
import TaskRecord from '@/views/system/task/TaskRecord'
|
||||
|
||||
import bus from '@/utils/bus'
|
||||
import { mapGetters } from 'vuex'
|
||||
export default {
|
||||
components: { DeLayoutContent, DatasetTaskList, TaskRecord },
|
||||
data() {
|
||||
return {
|
||||
tabActive: 'DatasetTaskList',
|
||||
transCondition: {},
|
||||
task: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['permission_routes'])
|
||||
},
|
||||
mounted() {
|
||||
bus.$on('to-msg-dataset', this.toMsgShare)
|
||||
},
|
||||
beforeDestroy() {
|
||||
bus.$off('to-msg-dataset', this.toMsgShare)
|
||||
},
|
||||
created() {
|
||||
this.$store.dispatch('app/toggleSideBarHide', false)
|
||||
const routerParam = this.$router.currentRoute.params
|
||||
routerParam &&
|
||||
this.$nextTick(() => {
|
||||
this.toMsgShare(routerParam)
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
changeTab() {
|
||||
this.task = null
|
||||
this.transCondition = {}
|
||||
},
|
||||
jumpTaskRecord({ id: taskId, name }) {
|
||||
this.transCondition = { taskId, name }
|
||||
this.tabActive = 'TaskRecord'
|
||||
},
|
||||
jumpTask({ taskId, name }) {
|
||||
this.transCondition = { taskId, name }
|
||||
this.tabActive = 'DatasetTaskList'
|
||||
},
|
||||
toMsgShare(routerParam) {
|
||||
if (routerParam !== null && routerParam.msgNotification) {
|
||||
const panelShareTypeIds = [4, 5, 6]
|
||||
// 说明是从消息通知跳转过来的
|
||||
if (panelShareTypeIds.includes(routerParam.msgType)) {
|
||||
// 是数据集同步
|
||||
if (routerParam.sourceParam) {
|
||||
this.openSystem()
|
||||
try {
|
||||
const msgParam = JSON.parse(routerParam.sourceParam)
|
||||
|
||||
this.$nextTick(() => {
|
||||
// 目标组件存在定时器 这种方式会被定时器阻塞
|
||||
this.task = msgParam
|
||||
this.tabActive = 'TaskRecord'
|
||||
})
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
openSystem() {
|
||||
const path = '/system'
|
||||
let route = this.permission_routes.find(
|
||||
(item) => item.path === '/' + path.split('/')[1]
|
||||
)
|
||||
// 如果找不到这个路由,说明是首页
|
||||
if (!route) {
|
||||
route = this.permission_routes.find((item) => item.path === '/')
|
||||
}
|
||||
this.$store.commit('permission/SET_CURRENT_ROUTES', route)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.de-task-record {
|
||||
height: 100%;
|
||||
background-color: var(--MainBG, #f5f6f7);
|
||||
|
||||
.tabs-container {
|
||||
height: calc(100% - 48px);
|
||||
background: var(--ContentBG, #ffffff);
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
::v-deep.el-tabs__header {
|
||||
margin: 0 0 12px;
|
||||
}
|
||||
|
||||
::v-deep.el-tabs__item {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
margin-bottom: 9px;
|
||||
padding: 0 12px;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -367,7 +367,7 @@ import { formatOrders } from '@/utils/index'
|
||||
import { datasetTaskList, post } from '@/api/dataset/dataset'
|
||||
import { hasDataPermission } from '@/utils/permission'
|
||||
import GridTable from '@/components/gridTable/index.vue'
|
||||
import filterUser from './filterUser.vue'
|
||||
import filterUser from './FilterUser.vue'
|
||||
import msgCfm from '@/components/msgCfm/index'
|
||||
import _ from 'lodash'
|
||||
import keyEnter from '@/components/msgCfm/keyEnter.js'
|
||||
|
355
frontend/src/views/system/task/FilterUser.vue
Normal file
355
frontend/src/views/system/task/FilterUser.vue
Normal file
@ -0,0 +1,355 @@
|
||||
<template>
|
||||
<el-drawer
|
||||
v-closePress
|
||||
:title="$t('user.filter_method')"
|
||||
:visible.sync="userDrawer"
|
||||
custom-class="de-user-drawer"
|
||||
size="680px"
|
||||
direction="rtl"
|
||||
>
|
||||
<div class="el-drawer__body-cont">
|
||||
<div class="filter">
|
||||
<span>{{ $t("dataset.datalist") }}</span>
|
||||
<div class="filter-item">
|
||||
<span
|
||||
v-for="ele in selectDatasetsCahe"
|
||||
:key="ele.id"
|
||||
class="item"
|
||||
:class="[activeDataset.includes(ele.id) ? 'active' : '']"
|
||||
@click="activeDatasetChange(ele.id)"
|
||||
>{{ ele.name }}</span>
|
||||
<el-popover
|
||||
placement="bottom"
|
||||
popper-class="user-popper"
|
||||
width="200"
|
||||
trigger="click"
|
||||
>
|
||||
<el-popover
|
||||
v-loading="treeLoading"
|
||||
placement="bottom"
|
||||
popper-class="user-popper dept"
|
||||
width="200"
|
||||
trigger="click"
|
||||
>
|
||||
<el-tree
|
||||
ref="datasetTreeRef"
|
||||
current-node-key="id"
|
||||
:data="treeData"
|
||||
node-key="id"
|
||||
highlight-current
|
||||
:filter-node-method="filterNode"
|
||||
:expand-on-click-node="true"
|
||||
@node-click="nodeClick"
|
||||
>
|
||||
<span
|
||||
slot-scope="{ data }"
|
||||
class="custom-tree-node"
|
||||
>
|
||||
<span v-if="data.modelInnerType === 'group'">
|
||||
<svg-icon icon-class="scene" />
|
||||
<span
|
||||
style="
|
||||
margin-left: 6px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
"
|
||||
:title="data.name"
|
||||
>{{ data.name }}</span>
|
||||
</span>
|
||||
<span v-else>
|
||||
<span>
|
||||
<svg-icon
|
||||
:icon-class="`ds-${data.modelInnerType}`"
|
||||
:class="`ds-icon-${data.modelInnerType}`"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
style="
|
||||
margin-left: 6px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
"
|
||||
:title="data.name"
|
||||
>{{ data.name }}</span>
|
||||
</span>
|
||||
</span>
|
||||
</el-tree>
|
||||
|
||||
<el-select
|
||||
ref="datasetSelect"
|
||||
slot="reference"
|
||||
v-model="selectDatasets"
|
||||
popper-class="tree-select"
|
||||
multiple
|
||||
:placeholder="$t('commons.please_select')"
|
||||
value-key="id"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in selectDatasets"
|
||||
:key="item.name"
|
||||
:label="item.name"
|
||||
:value="item"
|
||||
/>
|
||||
</el-select>
|
||||
</el-popover>
|
||||
<span
|
||||
slot="reference"
|
||||
class="more"
|
||||
>+ {{ $t("panel.more") }}</span>
|
||||
</el-popover>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-for="ele in filterDataset"
|
||||
:key="ele.name"
|
||||
class="filter"
|
||||
>
|
||||
<span>{{ $t(ele.name) }}</span>
|
||||
<div class="filter-item">
|
||||
<span
|
||||
v-for="item in ele.list"
|
||||
:key="item.name"
|
||||
class="item"
|
||||
:class="[active[ele.activeType].includes(item.value) ? 'active' : '']"
|
||||
@click="statusChange(item.value, ele.activeType)"
|
||||
>{{ $t(item.name) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="filter">
|
||||
<span>{{ $t("dedaterange.label") }}</span>
|
||||
<div class="filter-item">
|
||||
<DeDatePick v-model="dataRange" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="foot">
|
||||
<el-button
|
||||
class="btn normal"
|
||||
@click="reset"
|
||||
>{{
|
||||
$t("commons.reset")
|
||||
}}</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
class="btn"
|
||||
@click="search"
|
||||
>{{
|
||||
$t("commons.adv_search.search")
|
||||
}}</el-button>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { filterDataset, dateFormat } from './options'
|
||||
import { queryAuthModel } from '@/api/authModel/authModel'
|
||||
import DeDatePick from '@/components/deCustomCm/deDatePick.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DeDatePick
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
treeLoading: false,
|
||||
dataRange: [],
|
||||
selectDatasets: [],
|
||||
datasetCahe: [],
|
||||
activeDataset: [],
|
||||
selectDatasetsCahe: [],
|
||||
treeData: [],
|
||||
filterDataset,
|
||||
active: {
|
||||
execStatus: [],
|
||||
status: [],
|
||||
rate: []
|
||||
},
|
||||
userDrawer: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.treeNode()
|
||||
},
|
||||
methods: {
|
||||
treeNode() {
|
||||
this.treeLoading = true
|
||||
queryAuthModel(
|
||||
{
|
||||
modelType: 'dataset',
|
||||
privileges: 'manage',
|
||||
datasetMode: 1,
|
||||
clearEmptyDir: true,
|
||||
mode: 1,
|
||||
modelInnerTypeArray: ['db', 'sql', 'api', 'group']
|
||||
},
|
||||
true
|
||||
)
|
||||
.then((res) => {
|
||||
this.treeData = res.data
|
||||
})
|
||||
.finally(() => {
|
||||
this.treeLoading = false
|
||||
})
|
||||
},
|
||||
nodeClick(data) {
|
||||
const { id, name, modelInnerType: type } = data
|
||||
if (type === 'group') return
|
||||
this.handleNodeClick(id, name)
|
||||
},
|
||||
filterNode(value, data) {
|
||||
if (!value) return true
|
||||
return !this.activeDataset.includes(data.id)
|
||||
},
|
||||
clearFilter() {
|
||||
this.active = {
|
||||
execStatus: [],
|
||||
status: [],
|
||||
rate: []
|
||||
}
|
||||
this.dataRange = []
|
||||
this.activeDataset = []
|
||||
this.selectDatasets = []
|
||||
this.datasetCahe = []
|
||||
this.selectDatasetsCahe = []
|
||||
this.$refs.datasetTreeRef.filter()
|
||||
this.$emit('search', [], [])
|
||||
},
|
||||
clearOneFilter(index) {
|
||||
(this.filterTextMap[index] || []).forEach((ele) => {
|
||||
const eleKey = ele.split('.')
|
||||
if (eleKey.length === 2) {
|
||||
const [p, c] = eleKey
|
||||
this[p][c] = []
|
||||
} else {
|
||||
this[ele] = []
|
||||
}
|
||||
if (ele === 'activeDataset') {
|
||||
this.$refs.datasetTreeRef.filter()
|
||||
}
|
||||
})
|
||||
},
|
||||
statusChange(value, type) {
|
||||
const statusIndex = this.active[type].findIndex((ele) => ele === value)
|
||||
if (statusIndex === -1) {
|
||||
this.active[type].push(value)
|
||||
} else {
|
||||
this.active[type].splice(statusIndex, 1)
|
||||
}
|
||||
},
|
||||
handleNodeClick(id, name) {
|
||||
const datasetIdx = this.selectDatasets.findIndex((ele) => ele.id === id)
|
||||
if (datasetIdx !== -1) {
|
||||
this.selectDatasets.splice(datasetIdx, 1)
|
||||
}
|
||||
this.activeDataset.push(id)
|
||||
this.selectDatasetsCahe.push({ id, name })
|
||||
this.datasetCahe.push({ id, name })
|
||||
this.$refs.datasetTreeRef.filter(id)
|
||||
},
|
||||
activeDatasetChange(id) {
|
||||
const dataset = this.datasetCahe.find((ele) => ele.id === id)
|
||||
this.selectDatasets.push(dataset)
|
||||
this.activeDataset = this.activeDataset.filter((ele) => ele !== id)
|
||||
this.datasetCahe = this.datasetCahe.filter(
|
||||
(ele) => ele.id !== id
|
||||
)
|
||||
this.selectDatasetsCahe = this.selectDatasetsCahe.filter(
|
||||
(ele) => ele.id !== id
|
||||
)
|
||||
this.$refs.datasetTreeRef.filter(true)
|
||||
},
|
||||
search() {
|
||||
this.userDrawer = false
|
||||
this.$emit('search', this.formatCondition(), this.formatText())
|
||||
},
|
||||
formatText() {
|
||||
this.filterTextMap = []
|
||||
const params = []
|
||||
if (this.activeDataset.length) {
|
||||
const str = `${this.$t('dataset.datalist')}:${this.activeDataset.reduce(
|
||||
(pre, next) =>
|
||||
(this.datasetCahe.find((ele) => ele.id === next) || {}).name +
|
||||
'、' +
|
||||
pre,
|
||||
''
|
||||
)}`
|
||||
params.push(str.slice(0, str.length - 1))
|
||||
this.filterTextMap.push([
|
||||
'activeDataset',
|
||||
'selectDatasets',
|
||||
'selectDatasetsCahe',
|
||||
'datasetCahe'
|
||||
])
|
||||
}
|
||||
[
|
||||
'dataset.execute_rate',
|
||||
'dataset.task.task_status',
|
||||
'dataset.task.last_exec_status'
|
||||
].forEach((ele, index) => {
|
||||
const { activeType: type, list } =
|
||||
this.filterDataset[index]
|
||||
if (this.active[type].length) {
|
||||
params.push(
|
||||
`${this.$t(ele)}:${this.active[type]
|
||||
.map((item) => this.$t(list.find((itx) => itx.value === item).name))
|
||||
.join('、')}`
|
||||
)
|
||||
this.filterTextMap.push([`active.${type}`])
|
||||
}
|
||||
})
|
||||
if (this.dataRange.length) {
|
||||
params.push(
|
||||
`${this.$t('dedaterange.label')}:${this.dataRange
|
||||
.map((ele) => {
|
||||
return dateFormat('YYYY-mm-dd', ele)
|
||||
})
|
||||
.join('-')}`
|
||||
)
|
||||
this.filterTextMap.push(['dataRange'])
|
||||
}
|
||||
return params
|
||||
},
|
||||
formatCondition() {
|
||||
const fildMap = {
|
||||
'dataset_table_task.rate': this.active.rate,
|
||||
'dataset_table_task.status': this.active.status,
|
||||
'dataset_table_task.last_exec_status': this.active.execStatus,
|
||||
'dataset_table.id': this.activeDataset
|
||||
}
|
||||
const conditions = []
|
||||
Object.keys(fildMap).forEach((ele) => {
|
||||
if (fildMap[ele].length) {
|
||||
conditions.push({
|
||||
field: ele,
|
||||
operator: 'in',
|
||||
value: fildMap[ele]
|
||||
})
|
||||
}
|
||||
})
|
||||
// eslint-disable-next-line
|
||||
let [min, max] = this.dataRange
|
||||
if (min && max) {
|
||||
if (+min === +max) {
|
||||
max = +max + 24 * 3600 * 1000
|
||||
}
|
||||
conditions.push({
|
||||
field: 'dataset_table_task.last_exec_time',
|
||||
operator: 'between',
|
||||
value: [+min, +max]
|
||||
})
|
||||
}
|
||||
return conditions
|
||||
},
|
||||
init() {
|
||||
this.userDrawer = true
|
||||
},
|
||||
reset() {
|
||||
this.clearFilter()
|
||||
this.userDrawer = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
349
frontend/src/views/system/task/FilterUserRecord.vue
Normal file
349
frontend/src/views/system/task/FilterUserRecord.vue
Normal file
@ -0,0 +1,349 @@
|
||||
<template>
|
||||
<el-drawer
|
||||
v-closePress
|
||||
:title="$t('user.filter_method')"
|
||||
:visible.sync="userDrawer"
|
||||
custom-class="de-user-drawer"
|
||||
size="680px"
|
||||
direction="rtl"
|
||||
>
|
||||
<div class="el-drawer__body-cont">
|
||||
<div class="filter">
|
||||
<span>{{ $t("dataset.datalist") }}</span>
|
||||
<div class="filter-item">
|
||||
<span
|
||||
v-for="ele in selectDatasetsCahe"
|
||||
:key="ele.id"
|
||||
class="item"
|
||||
:class="[activeDataset.includes(ele.id) ? 'active' : '']"
|
||||
@click="activeDatasetChange(ele.id)"
|
||||
>{{ ele.name }}</span>
|
||||
<el-popover
|
||||
placement="bottom"
|
||||
popper-class="user-popper"
|
||||
width="200"
|
||||
trigger="click"
|
||||
>
|
||||
<el-popover
|
||||
v-loading="treeLoading"
|
||||
placement="bottom"
|
||||
popper-class="user-popper dept"
|
||||
width="200"
|
||||
trigger="click"
|
||||
>
|
||||
<el-tree
|
||||
ref="datasetTreeRef"
|
||||
current-node-key="id"
|
||||
:data="treeData"
|
||||
node-key="id"
|
||||
highlight-current
|
||||
:filter-node-method="filterNode"
|
||||
:expand-on-click-node="true"
|
||||
@node-click="nodeClick"
|
||||
>
|
||||
<span
|
||||
slot-scope="{ data }"
|
||||
class="custom-tree-node"
|
||||
>
|
||||
<span v-if="data.modelInnerType === 'group'">
|
||||
<svg-icon icon-class="scene" />
|
||||
<span
|
||||
style="
|
||||
margin-left: 6px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
"
|
||||
:title="data.name"
|
||||
>{{ data.name }}</span>
|
||||
</span>
|
||||
<span v-else>
|
||||
<span>
|
||||
<svg-icon
|
||||
:icon-class="`ds-${data.modelInnerType}`"
|
||||
:class="`ds-icon-${data.modelInnerType}`"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
style="
|
||||
margin-left: 6px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
"
|
||||
:title="data.name"
|
||||
>{{ data.name }}</span>
|
||||
</span>
|
||||
</span>
|
||||
</el-tree>
|
||||
|
||||
<el-select
|
||||
ref="datasetSelect"
|
||||
slot="reference"
|
||||
v-model="selectDatasets"
|
||||
popper-class="tree-select"
|
||||
multiple
|
||||
:placeholder="$t('commons.please_select')"
|
||||
value-key="id"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in selectDatasets"
|
||||
:key="item.name"
|
||||
:label="item.name"
|
||||
:value="item"
|
||||
/>
|
||||
</el-select>
|
||||
</el-popover>
|
||||
<span
|
||||
slot="reference"
|
||||
class="more"
|
||||
>+ {{ $t("panel.more") }}</span>
|
||||
</el-popover>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-for="ele in filterDataset"
|
||||
:key="ele.name"
|
||||
class="filter"
|
||||
>
|
||||
<span>{{ $t(ele.name) }}</span>
|
||||
<div class="filter-item">
|
||||
<span
|
||||
v-for="item in ele.list"
|
||||
:key="item.name"
|
||||
class="item"
|
||||
:class="[
|
||||
active[ele.activeType].includes(item.value) ? 'active' : '',
|
||||
]"
|
||||
@click="statusChange(item.value, ele.activeType)"
|
||||
>{{ $t(item.name) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="filter">
|
||||
<span>{{ $t("dedaterange.label") }}</span>
|
||||
<div class="filter-item">
|
||||
<DeDatePick v-model="dataRange" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="foot">
|
||||
<el-button
|
||||
class="btn normal"
|
||||
@click="reset"
|
||||
>{{
|
||||
$t("commons.reset")
|
||||
}}</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
class="btn"
|
||||
@click="search"
|
||||
>{{
|
||||
$t("commons.adv_search.search")
|
||||
}}</el-button>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { filterDatasetRecord, dateFormat } from './options'
|
||||
import { queryAuthModel } from '@/api/authModel/authModel'
|
||||
import DeDatePick from '@/components/deCustomCm/deDatePick.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DeDatePick
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
treeLoading: false,
|
||||
filterTextMap: [],
|
||||
dataRange: [],
|
||||
selectDatasets: [],
|
||||
datasetCahe: [],
|
||||
activeDataset: [],
|
||||
selectDatasetsCahe: [],
|
||||
treeData: [],
|
||||
filterDataset: [filterDatasetRecord],
|
||||
active: {
|
||||
execStatus: []
|
||||
},
|
||||
userDrawer: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.treeNode()
|
||||
},
|
||||
methods: {
|
||||
treeNode() {
|
||||
this.treeLoading = true
|
||||
queryAuthModel(
|
||||
{
|
||||
modelType: 'dataset',
|
||||
privileges: 'manage',
|
||||
datasetMode: 1,
|
||||
clearEmptyDir: true,
|
||||
mode: 1,
|
||||
modelInnerTypeArray: ['db', 'sql', 'api', 'group']
|
||||
},
|
||||
true
|
||||
)
|
||||
.then((res) => {
|
||||
this.treeData = res.data
|
||||
})
|
||||
.finally(() => {
|
||||
this.treeLoading = false
|
||||
})
|
||||
},
|
||||
nodeClick(data) {
|
||||
const { id, name, modelInnerType: type } = data
|
||||
if (type === 'group') return
|
||||
this.handleNodeClick(id, name)
|
||||
},
|
||||
filterNode(value, data) {
|
||||
if (!value) return true
|
||||
return !this.activeDataset.includes(data.id)
|
||||
},
|
||||
clearFilter() {
|
||||
this.active = {
|
||||
execStatus: []
|
||||
}
|
||||
this.dataRange = []
|
||||
this.activeDataset = []
|
||||
this.selectDatasets = []
|
||||
this.datasetCahe = []
|
||||
this.selectDatasetsCahe = []
|
||||
this.$refs.datasetTreeRef.filter()
|
||||
this.$emit('search', [], [])
|
||||
},
|
||||
clearOneFilter(index) {
|
||||
(this.filterTextMap[index] || []).forEach((ele) => {
|
||||
const eleKey = ele.split('.')
|
||||
if (eleKey.length === 2) {
|
||||
const [p, c] = eleKey
|
||||
this[p][c] = []
|
||||
} else {
|
||||
this[ele] = []
|
||||
}
|
||||
if (ele === 'activeDataset') {
|
||||
this.$refs.datasetTreeRef.filter()
|
||||
}
|
||||
})
|
||||
},
|
||||
statusChange(value, type) {
|
||||
const statusIndex = this.active[type].findIndex((ele) => ele === value)
|
||||
if (statusIndex === -1) {
|
||||
this.active[type].push(value)
|
||||
} else {
|
||||
this.active[type].splice(statusIndex, 1)
|
||||
}
|
||||
},
|
||||
handleNodeClick(id, name) {
|
||||
const datasetIdx = this.selectDatasets.findIndex((ele) => ele.id === id)
|
||||
if (datasetIdx !== -1) {
|
||||
this.selectDatasets.splice(datasetIdx, 1)
|
||||
}
|
||||
this.activeDataset.push(id)
|
||||
this.selectDatasetsCahe.push({ id, name })
|
||||
this.datasetCahe.push({ id, name })
|
||||
this.$refs.datasetTreeRef.filter(id)
|
||||
},
|
||||
activeDatasetChange(id) {
|
||||
const dataset = this.datasetCahe.find((ele) => ele.id === id)
|
||||
this.selectDatasets.push(dataset)
|
||||
this.activeDataset = this.activeDataset.filter((ele) => ele !== id)
|
||||
this.datasetCahe = this.datasetCahe.filter(
|
||||
(ele) => ele.id !== id
|
||||
)
|
||||
this.selectDatasetsCahe = this.selectDatasetsCahe.filter(
|
||||
(ele) => ele.id !== id
|
||||
)
|
||||
this.$refs.datasetTreeRef.filter(true)
|
||||
},
|
||||
search() {
|
||||
this.userDrawer = false
|
||||
this.$emit('search', this.formatCondition(), this.formatText())
|
||||
},
|
||||
formatText() {
|
||||
this.filterTextMap = []
|
||||
const params = []
|
||||
if (this.activeDataset.length) {
|
||||
const str = `${this.$t('dataset.datalist')}:${this.activeDataset.reduce(
|
||||
(pre, next) =>
|
||||
(this.datasetCahe.find((ele) => ele.id === next) || {}).name +
|
||||
'、' +
|
||||
pre,
|
||||
''
|
||||
)}`
|
||||
params.push(str.slice(0, str.length - 1))
|
||||
this.filterTextMap.push([
|
||||
'activeDataset',
|
||||
'selectDatasets',
|
||||
'selectDatasetsCahe',
|
||||
'datasetCahe'
|
||||
])
|
||||
}
|
||||
['dataset.task.last_exec_status'].forEach((ele, index) => {
|
||||
const { activeType: type, list } = this.filterDataset[index]
|
||||
if (this.active[type].length) {
|
||||
params.push(
|
||||
`${this.$t(ele)}:${this.active[type]
|
||||
.map((item) =>
|
||||
this.$t(list.find((itx) => itx.value === item).name)
|
||||
)
|
||||
.join('、')}`
|
||||
)
|
||||
this.filterTextMap.push([`active.${type}`])
|
||||
}
|
||||
})
|
||||
if (this.dataRange.length) {
|
||||
params.push(
|
||||
`${this.$t('dedaterange.label')}:${this.dataRange
|
||||
.map((ele) => {
|
||||
return dateFormat('YYYY-mm-dd', ele)
|
||||
})
|
||||
.join('-')}`
|
||||
)
|
||||
this.filterTextMap.push(['dataRange'])
|
||||
}
|
||||
return params
|
||||
},
|
||||
formatCondition() {
|
||||
const fildMap = {
|
||||
'dataset_table_task.last_exec_status': this.active.execStatus,
|
||||
'dataset_table.id': this.activeDataset
|
||||
}
|
||||
const conditions = []
|
||||
Object.keys(fildMap).forEach((ele) => {
|
||||
if (fildMap[ele].length) {
|
||||
conditions.push({
|
||||
field: ele,
|
||||
operator: 'in',
|
||||
value: fildMap[ele]
|
||||
})
|
||||
}
|
||||
})
|
||||
// eslint-disable-next-line
|
||||
let [min, max] = this.dataRange
|
||||
if (min && max) {
|
||||
if (+min === +max) {
|
||||
max = +max + 24 * 3600 * 1000
|
||||
}
|
||||
conditions.push({
|
||||
field: 'dataset_table_task.last_exec_time',
|
||||
operator: 'between',
|
||||
value: [+min, +max]
|
||||
})
|
||||
}
|
||||
return conditions
|
||||
},
|
||||
init() {
|
||||
this.userDrawer = true
|
||||
},
|
||||
reset() {
|
||||
this.clearFilter()
|
||||
this.userDrawer = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
692
frontend/src/views/system/task/Form.vue
Normal file
692
frontend/src/views/system/task/Form.vue
Normal file
@ -0,0 +1,692 @@
|
||||
<template>
|
||||
<de-layout-content
|
||||
:header="header"
|
||||
back-path="/system/system-task/dataset"
|
||||
>
|
||||
<div class="dataset-editer-form">
|
||||
<div class="w600">
|
||||
<el-form
|
||||
ref="taskForm"
|
||||
:form="taskForm"
|
||||
:model="taskForm"
|
||||
:disabled="disableForm"
|
||||
label-width="100px"
|
||||
class="de-form-item"
|
||||
:rules="taskFormRules"
|
||||
>
|
||||
<el-form-item
|
||||
:label="$t('chart.select_dataset')"
|
||||
prop="datasetName"
|
||||
@click.native="selectDataset"
|
||||
>
|
||||
<el-input
|
||||
v-model="taskForm.datasetName"
|
||||
size="small"
|
||||
:disabled="!!taskForm.id"
|
||||
readonly
|
||||
:placeholder="$t('dataset.task_name')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="$t('dataset.task_name')"
|
||||
prop="name"
|
||||
>
|
||||
<el-input
|
||||
v-model="taskForm.name"
|
||||
size="small"
|
||||
:placeholder="$t('dataset.task_name')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="$t('dataset.update_type')"
|
||||
prop="type"
|
||||
>
|
||||
<el-radio-group v-model="taskForm.type">
|
||||
<el-radio label="all_scope">{{
|
||||
$t("dataset.all_scope")
|
||||
}}</el-radio>
|
||||
<el-radio label="add_scope">
|
||||
{{ $t("dataset.add_scope") }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<div
|
||||
v-if="taskForm.type === 'add_scope'"
|
||||
class="add-scope-cont"
|
||||
>
|
||||
<el-form-item
|
||||
prop="type"
|
||||
:label="$t('dataset.incremental_update_type')"
|
||||
>
|
||||
<el-radio-group
|
||||
v-model="incrementalUpdateType"
|
||||
size="small"
|
||||
@change="incrementalUpdateTypeChange"
|
||||
>
|
||||
<el-radio label="incrementalAdd">{{
|
||||
$t("dataset.incremental_add")
|
||||
}}</el-radio>
|
||||
<el-radio label="incrementalDelete">{{
|
||||
$t("dataset.incremental_delete")
|
||||
}}</el-radio>
|
||||
</el-radio-group>
|
||||
<div class="param-title">
|
||||
<span>{{ $t("dataset.param") }}</span>
|
||||
<div class="param-title-btn">
|
||||
<el-button
|
||||
type="text"
|
||||
size="small"
|
||||
@click="insertParamToCodeMirror('${__last_update_time__}')"
|
||||
>{{ $t("dataset.last_update_time") }}</el-button>
|
||||
<el-button
|
||||
type="text"
|
||||
size="small"
|
||||
@click="
|
||||
insertParamToCodeMirror('${__current_update_time__}')
|
||||
"
|
||||
>{{ $t("dataset.current_update_time") }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="codemirror-cont">
|
||||
<codemirror
|
||||
ref="myCm"
|
||||
v-model="sql"
|
||||
class="codemirror"
|
||||
:options="sqlOption"
|
||||
@ready="onCmReady"
|
||||
@focus="onCmFocus"
|
||||
@input="onCmCodeChange"
|
||||
/>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
<el-form-item
|
||||
:label="$t('dataset.execute_rate')"
|
||||
prop="rate"
|
||||
>
|
||||
<el-radio-group
|
||||
v-model="taskForm.rate"
|
||||
@change="onRateChange"
|
||||
>
|
||||
<el-radio label="SIMPLE">{{
|
||||
$t("dataset.execute_once")
|
||||
}}</el-radio>
|
||||
<el-radio label="CRON">{{ $t("dataset.cron_config") }}</el-radio>
|
||||
<el-radio label="SIMPLE_CRON">{{
|
||||
$t("dataset.simple_cron")
|
||||
}}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<div
|
||||
v-if="taskForm.rate !== 'SIMPLE'"
|
||||
class="execute-rate-cont"
|
||||
>
|
||||
<el-form-item
|
||||
v-if="taskForm.rate === 'SIMPLE_CRON'"
|
||||
:label="$t('dataset.execute_rate')"
|
||||
prop="rate"
|
||||
>
|
||||
<div class="simple-cron">
|
||||
{{ $t("cron.every") }}
|
||||
<el-input-number
|
||||
v-model="taskForm.extraData.simple_cron_value"
|
||||
controls-position="right"
|
||||
:min="1"
|
||||
size="small"
|
||||
@change="onSimpleCronChange()"
|
||||
/>
|
||||
<el-select
|
||||
v-model="taskForm.extraData.simple_cron_type"
|
||||
filterable
|
||||
size="small"
|
||||
@change="onSimpleCronChange()"
|
||||
>
|
||||
<el-option
|
||||
:label="$t('components.minute')"
|
||||
value="minute"
|
||||
/>
|
||||
<el-option
|
||||
:label="$t('components.hour')"
|
||||
value="hour"
|
||||
/>
|
||||
<el-option
|
||||
:label="$t('components.day')"
|
||||
value="day"
|
||||
/>
|
||||
</el-select>
|
||||
{{ $t("cron.every_exec") }}
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="taskForm.rate === 'CRON' && showCron"
|
||||
prop="cron"
|
||||
:label="$t('emailtask.cron_exp')"
|
||||
>
|
||||
<el-popover v-model="cronEdit">
|
||||
<cron
|
||||
v-model="taskForm.cron"
|
||||
:is-rate="taskForm.rate === 'CRON'"
|
||||
@close="cronEdit = false"
|
||||
/>
|
||||
<el-input
|
||||
slot="reference"
|
||||
v-model="taskForm.cron"
|
||||
size="small"
|
||||
style="width: 50%"
|
||||
@click="cronEdit = true"
|
||||
/>
|
||||
</el-popover>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="taskForm.rate !== 'SIMPLE'"
|
||||
:label="$t('dataset.start_time')"
|
||||
prop="startTime"
|
||||
>
|
||||
<el-date-picker
|
||||
v-model="taskForm.startTime"
|
||||
class="de-date-picker"
|
||||
type="datetime"
|
||||
:placeholder="$t('dataset.start_time')"
|
||||
size="small"
|
||||
/>
|
||||
<svg-icon
|
||||
icon-class="icon_calendar_outlined"
|
||||
class="icon-calendar-outlined"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="taskForm.rate !== 'SIMPLE'"
|
||||
:label="$t('dataset.end_time')"
|
||||
prop="end"
|
||||
>
|
||||
<el-radio-group v-model="taskForm.end">
|
||||
<el-radio label="0">{{ $t("dataset.no_limit") }}</el-radio>
|
||||
<el-radio label="1"> {{ $t("dataset.set_end_time") }}</el-radio>
|
||||
</el-radio-group>
|
||||
<el-date-picker
|
||||
v-if="taskForm.end === '1'"
|
||||
v-model="taskForm.endTime"
|
||||
class="de-date-picker"
|
||||
type="datetime"
|
||||
:placeholder="$t('dataset.end_time')"
|
||||
size="small"
|
||||
/>
|
||||
<svg-icon
|
||||
v-if="taskForm.end === '1'"
|
||||
icon-class="icon_calendar_outlined"
|
||||
class="icon-calendar-outlined"
|
||||
/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
<table-selector
|
||||
ref="tableSelector"
|
||||
preview-for-task="true"
|
||||
privileges="manage"
|
||||
:mode="1"
|
||||
:clear-empty-dir="true"
|
||||
:custom-type="['db', 'sql', 'api']"
|
||||
show-mode="datasetTask"
|
||||
@getTableId="getTableId"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-if="!disableForm"
|
||||
class="de-foot-layout"
|
||||
>
|
||||
<div class="cont">
|
||||
<deBtn
|
||||
secondary
|
||||
@click="closeTask"
|
||||
>{{ $t("dataset.cancel") }}</deBtn>
|
||||
<deBtn
|
||||
type="primary"
|
||||
@click="saveTask(taskForm)"
|
||||
>{{
|
||||
$t("dataset.confirm")
|
||||
}}</deBtn>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</de-layout-content>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { post } from '@/api/dataset/dataset'
|
||||
import DeLayoutContent from '@/components/business/DeLayoutContent'
|
||||
import { hasDataPermission } from '@/utils/permission'
|
||||
import msgCfm from '@/components/msgCfm/index'
|
||||
|
||||
import cron from '@/components/cron/cron'
|
||||
import { codemirror } from 'vue-codemirror'
|
||||
import 'codemirror/lib/codemirror.css'
|
||||
import 'codemirror/theme/eclipse.css'
|
||||
import 'codemirror/mode/sql/sql.js'
|
||||
import 'codemirror/addon/selection/active-line.js'
|
||||
import 'codemirror/addon/edit/closebrackets.js'
|
||||
import 'codemirror/mode/clike/clike.js'
|
||||
import 'codemirror/addon/edit/matchbrackets.js'
|
||||
import 'codemirror/addon/comment/comment.js'
|
||||
import 'codemirror/addon/dialog/dialog.js'
|
||||
import 'codemirror/addon/dialog/dialog.css'
|
||||
import 'codemirror/addon/search/searchcursor.js'
|
||||
import 'codemirror/addon/search/search.js'
|
||||
import 'codemirror/keymap/emacs.js'
|
||||
import 'codemirror/addon/hint/show-hint.css'
|
||||
import 'codemirror/addon/hint/sql-hint'
|
||||
import 'codemirror/addon/hint/show-hint'
|
||||
import TableSelector from './TableSelector'
|
||||
|
||||
export default {
|
||||
components: { cron, codemirror, TableSelector, DeLayoutContent },
|
||||
mixins: [msgCfm],
|
||||
data() {
|
||||
return {
|
||||
disableForm: false,
|
||||
table: {
|
||||
name: '',
|
||||
id: ''
|
||||
},
|
||||
showCron: false,
|
||||
taskForm: {
|
||||
name: '',
|
||||
type: 'all_scope',
|
||||
startTime: '',
|
||||
tableId: '',
|
||||
rate: 'SIMPLE',
|
||||
cron: '',
|
||||
endTime: '',
|
||||
end: '0',
|
||||
extraData: {
|
||||
simple_cron_type: 'hour',
|
||||
simple_cron_value: 1
|
||||
}
|
||||
},
|
||||
taskFormRules: {
|
||||
name: [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('dataset.required'),
|
||||
trigger: 'change'
|
||||
},
|
||||
{
|
||||
min: 2,
|
||||
max: 50,
|
||||
message: this.$t('datasource.input_limit_2_50', [2, 50]),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
type: [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('dataset.required'),
|
||||
trigger: 'change'
|
||||
}
|
||||
],
|
||||
startTime: [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('components.time_is_required'),
|
||||
trigger: 'change'
|
||||
}
|
||||
],
|
||||
rate: [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('dataset.required'),
|
||||
trigger: 'change'
|
||||
}
|
||||
],
|
||||
end: [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('dataset.required'),
|
||||
trigger: 'change'
|
||||
}
|
||||
],
|
||||
cron: [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('dataset.required'),
|
||||
trigger: 'change'
|
||||
}
|
||||
],
|
||||
datasetName: [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('components.data_set_required'),
|
||||
trigger: 'change'
|
||||
}
|
||||
]
|
||||
},
|
||||
cronEdit: false,
|
||||
sqlOption: {
|
||||
tabSize: 2,
|
||||
styleActiveLine: true,
|
||||
lineNumbers: true,
|
||||
line: true,
|
||||
mode: 'text/x-sql',
|
||||
theme: 'eclipse',
|
||||
hintOptions: {
|
||||
// 自定义提示选项
|
||||
completeSingle: false // 当匹配只有一项的时候是否自动补全
|
||||
}
|
||||
},
|
||||
incrementalConfig: {},
|
||||
sql: '',
|
||||
incrementalUpdateType: 'incrementalAdd'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
header() {
|
||||
return this.disableForm
|
||||
? '查看任务'
|
||||
: this.taskDetail.id
|
||||
? '编辑任务'
|
||||
: '添加任务'
|
||||
}
|
||||
},
|
||||
created() {
|
||||
const { datasetName, id, tableId } = this.$route.query
|
||||
this.taskDetail = { datasetName, id, tableId }
|
||||
if (!id) {
|
||||
this.taskForm.startTime = new Date()
|
||||
return
|
||||
}
|
||||
this.getTaskDetail(id)
|
||||
this.getIncrementalConfig(tableId)
|
||||
},
|
||||
methods: {
|
||||
getTaskDetail(id) {
|
||||
post(`/dataset/task/detail/${id}`, {}).then((res) => {
|
||||
if (res.data.extraData) {
|
||||
res.data.extraData = JSON.parse(res.data.extraData)
|
||||
}
|
||||
this.taskForm = res.data
|
||||
this.showCron = this.taskForm.rate === 'CRON'
|
||||
this.disableForm = this.disableEdit()
|
||||
})
|
||||
},
|
||||
selectDataset() {
|
||||
if (this.taskForm.id) return
|
||||
this.$refs.tableSelector.init()
|
||||
},
|
||||
getTableId(id, name) {
|
||||
this.taskForm.tableId = id
|
||||
this.$set(this.taskForm, 'datasetName', name)
|
||||
},
|
||||
onRateChange() {
|
||||
if (this.taskForm.rate === 'SIMPLE') {
|
||||
this.taskForm.end = '0'
|
||||
this.taskForm.endTime = ''
|
||||
this.taskForm.cron = ''
|
||||
this.showCron = false
|
||||
}
|
||||
if (this.taskForm.rate === 'SIMPLE_CRON') {
|
||||
this.taskForm.cron = '0 0 0/1 * * ? *'
|
||||
this.showCron = false
|
||||
}
|
||||
if (this.taskForm.rate === 'CRON') {
|
||||
this.taskForm.cron = '00 00 * ? * * *'
|
||||
this.$nextTick(() => {
|
||||
this.showCron = true
|
||||
})
|
||||
}
|
||||
},
|
||||
disableEdit() {
|
||||
const { privileges, rate, status } = this.taskForm
|
||||
return (
|
||||
rate === 'SIMPLE' ||
|
||||
status === 'Stopped' ||
|
||||
!hasDataPermission('manage', privileges)
|
||||
)
|
||||
},
|
||||
onCmReady(cm) {},
|
||||
onCmFocus(cm) {},
|
||||
onCmCodeChange(newCode) {
|
||||
this.sql = newCode
|
||||
this.$emit('codeChange', this.sql)
|
||||
},
|
||||
closeTask() {
|
||||
this.$router.back()
|
||||
},
|
||||
onSimpleCronChange() {
|
||||
if (this.taskForm.extraData.simple_cron_type === 'minute') {
|
||||
if (
|
||||
this.taskForm.extraData.simple_cron_value < 1 ||
|
||||
this.taskForm.extraData.simple_cron_value > 59
|
||||
) {
|
||||
this.$message({
|
||||
message: this.$t('cron.minute_limit'),
|
||||
type: 'warning',
|
||||
showClose: true
|
||||
})
|
||||
this.taskForm.extraData.simple_cron_value = 59
|
||||
}
|
||||
this.taskForm.cron =
|
||||
'0 0/' + this.taskForm.extraData.simple_cron_value + ' * * * ? *'
|
||||
return
|
||||
}
|
||||
if (this.taskForm.extraData.simple_cron_type === 'hour') {
|
||||
if (
|
||||
this.taskForm.extraData.simple_cron_value < 1 ||
|
||||
this.taskForm.extraData.simple_cron_value > 23
|
||||
) {
|
||||
this.$message({
|
||||
message: this.$t('cron.hour_limit'),
|
||||
type: 'warning',
|
||||
showClose: true
|
||||
})
|
||||
this.taskForm.extraData.simple_cron_value = 23
|
||||
}
|
||||
this.taskForm.cron =
|
||||
'0 0 0/' + this.taskForm.extraData.simple_cron_value + ' * * ? *'
|
||||
return
|
||||
}
|
||||
if (this.taskForm.extraData.simple_cron_type === 'day') {
|
||||
if (
|
||||
this.taskForm.extraData.simple_cron_value < 1 ||
|
||||
this.taskForm.extraData.simple_cron_value > 31
|
||||
) {
|
||||
this.$message({
|
||||
message: this.$t('cron.day_limit'),
|
||||
type: 'warning',
|
||||
showClose: true
|
||||
})
|
||||
this.taskForm.extraData.simple_cron_value = 31
|
||||
}
|
||||
this.taskForm.cron =
|
||||
'0 0 0 1/' + this.taskForm.extraData.simple_cron_value + ' * ? *'
|
||||
return
|
||||
}
|
||||
},
|
||||
insertParamToCodeMirror(param) {
|
||||
const pos1 = this.$refs.myCm.codemirror.getCursor()
|
||||
const pos2 = {}
|
||||
pos2.line = pos1.line
|
||||
pos2.ch = pos1.ch
|
||||
this.$refs.myCm.codemirror.replaceRange(param, pos2)
|
||||
},
|
||||
saveTask(task) {
|
||||
this.$refs.taskForm.validate((valid) => {
|
||||
if (valid) {
|
||||
if (task.rate !== 'SIMPLE') {
|
||||
if (this.incrementalUpdateType === 'incrementalAdd') {
|
||||
this.incrementalConfig.incrementalAdd = this.sql
|
||||
} else {
|
||||
this.incrementalConfig.incrementalDelete = this.sql
|
||||
}
|
||||
this.incrementalConfig.tableId = task.tableId
|
||||
}
|
||||
task.startTime = new Date(task.startTime).getTime()
|
||||
task.endTime = new Date(task.endTime).getTime()
|
||||
const form = JSON.parse(JSON.stringify(task))
|
||||
form.extraData = JSON.stringify(form.extraData)
|
||||
const dataSetTaskRequest = {
|
||||
datasetTableTask: form,
|
||||
datasetTableIncrementalConfig:
|
||||
task.type === 'add_scope' ? this.incrementalConfig : undefined
|
||||
}
|
||||
post('/dataset/task/save', dataSetTaskRequest).then((response) => {
|
||||
this.openMessageSuccess('dataset.save_success')
|
||||
this.closeTask()
|
||||
})
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
getIncrementalConfig(tableId) {
|
||||
post('/dataset/table/incrementalConfig', { tableId: tableId }).then(
|
||||
(response) => {
|
||||
this.incrementalConfig = response.data
|
||||
|
||||
if (
|
||||
this.incrementalConfig.incrementalAdd.length === 0 &&
|
||||
this.incrementalConfig.incrementalDelete.length === 0
|
||||
) {
|
||||
this.incrementalUpdateType = 'incrementalAdd'
|
||||
this.sql = ''
|
||||
return
|
||||
}
|
||||
if (this.incrementalConfig.incrementalAdd.length > 0) {
|
||||
this.incrementalUpdateType = 'incrementalAdd'
|
||||
this.sql = this.incrementalConfig.incrementalAdd
|
||||
} else {
|
||||
this.incrementalUpdateType = 'incrementalDelete'
|
||||
this.sql = this.incrementalConfig.incrementalDelete
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
incrementalUpdateTypeChange: function() {
|
||||
if (this.incrementalUpdateType === 'incrementalAdd') {
|
||||
if (this.sql) {
|
||||
this.incrementalConfig.incrementalDelete = this.sql
|
||||
} else {
|
||||
this.incrementalConfig.incrementalDelete = ''
|
||||
}
|
||||
if (this.incrementalConfig.incrementalAdd) {
|
||||
this.sql = this.incrementalConfig.incrementalAdd
|
||||
} else {
|
||||
this.sql = ''
|
||||
}
|
||||
}
|
||||
|
||||
if (this.incrementalUpdateType === 'incrementalDelete') {
|
||||
if (this.sql) {
|
||||
this.incrementalConfig.incrementalAdd = this.sql
|
||||
} else {
|
||||
this.incrementalConfig.incrementalAdd = ''
|
||||
}
|
||||
if (this.incrementalConfig.incrementalDelete) {
|
||||
this.sql = this.incrementalConfig.incrementalDelete
|
||||
} else {
|
||||
this.sql = ''
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.dataset-editer-form {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
.w600 {
|
||||
width: 600px;
|
||||
padding-top: 24px;
|
||||
padding-bottom: 24px;
|
||||
.el-radio:not(:last-child) {
|
||||
margin-right: 0;
|
||||
width: 156px;
|
||||
}
|
||||
|
||||
.simple-cron {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
.el-input-number,
|
||||
.el-select {
|
||||
width: 140px;
|
||||
margin-left: 8px;
|
||||
|
||||
.el-input__inner {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
.el-select {
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.execute-rate-cont {
|
||||
box-sizing: border-box;
|
||||
padding: 20px;
|
||||
width: 100%;
|
||||
background-color: var(--MainBG, #f5f6f7);
|
||||
border-radius: 4px;
|
||||
|
||||
.el-input__inner {
|
||||
background: var(--ContentBG, #ffffff) !important;
|
||||
}
|
||||
|
||||
.el-date-editor {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.add-scope-cont {
|
||||
height: 350px;
|
||||
width: 100%;
|
||||
border-radius: 4px;
|
||||
padding: 20px;
|
||||
background-color: var(--MainBG, #f5f6f7);
|
||||
|
||||
.param-title {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-bottom: 9px;
|
||||
&:nth-child(1) {
|
||||
font-family: PingFang SC;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: var(--deTextPrimary, #1f2329);
|
||||
}
|
||||
}
|
||||
|
||||
.codemirror-cont {
|
||||
box-sizing: border-box;
|
||||
width: 560px;
|
||||
height: 200px;
|
||||
background: #ffffff;
|
||||
border: 1px solid #bbbfc4;
|
||||
border-radius: 4px;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.de-foot-layout {
|
||||
position: absolute;
|
||||
width: calc(100% - 48px);
|
||||
height: 80px;
|
||||
bottom: 0;
|
||||
right: 24px;
|
||||
background-color: var(--MainBG, #fff);
|
||||
box-shadow: 0px -2px 4px rgba(0, 0, 0, 0.08);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 10;
|
||||
.cont {
|
||||
width: 600px;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -176,7 +176,7 @@ import {
|
||||
} from '@/utils/index'
|
||||
import { exportExcel, post } from '@/api/dataset/dataset'
|
||||
import GridTable from '@/components/gridTable/index.vue'
|
||||
import filterUser from './filterUserRecord.vue'
|
||||
import filterUser from './FilterUserRecord.vue'
|
||||
import _ from 'lodash'
|
||||
import keyEnter from '@/components/msgCfm/keyEnter.js'
|
||||
|
||||
|
@ -90,11 +90,9 @@ export default {
|
||||
this.openSystem()
|
||||
try {
|
||||
const msgParam = JSON.parse(routerParam.sourceParam)
|
||||
// this.param = msgParam.tableId
|
||||
|
||||
this.$nextTick(() => {
|
||||
// 目标组件存在定时器 这种方式会被定时器阻塞
|
||||
// this.$refs.task_record && this.$refs.task_record.msg2Current && this.$refs.task_record.msg2Current(msgParam)
|
||||
this.task = msgParam
|
||||
this.tabActive = 'TaskRecord'
|
||||
})
|
||||
@ -115,7 +113,6 @@ export default {
|
||||
route = this.permission_routes.find((item) => item.path === '/')
|
||||
}
|
||||
this.$store.commit('permission/SET_CURRENT_ROUTES', route)
|
||||
// this.setSidebarHide(route)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -441,9 +441,7 @@ export default {
|
||||
!hasDataPermission('manage', privileges)
|
||||
)
|
||||
},
|
||||
onCmReady(cm) {
|
||||
// this.codemirror.setSize("-webkit-fill-available", "auto");
|
||||
},
|
||||
onCmReady(cm) {},
|
||||
onCmFocus(cm) {},
|
||||
onCmCodeChange(newCode) {
|
||||
this.sql = newCode
|
||||
|
376
frontend/src/views/system/user/FilterUser.vue
Normal file
376
frontend/src/views/system/user/FilterUser.vue
Normal file
@ -0,0 +1,376 @@
|
||||
<template>
|
||||
<el-drawer
|
||||
v-closePress
|
||||
:title="$t('user.filter_method')"
|
||||
:visible.sync="userDrawer"
|
||||
custom-class="de-user-drawer"
|
||||
size="680px"
|
||||
direction="rtl"
|
||||
>
|
||||
<div class="el-drawer__body-cont">
|
||||
<div class="filter">
|
||||
<span>{{ $t("commons.status") }}</span>
|
||||
<div class="filter-item">
|
||||
<span
|
||||
v-for="ele in status"
|
||||
:key="ele.id"
|
||||
class="item"
|
||||
:class="[activeStatus.includes(ele.id) ? 'active' : '']"
|
||||
@click="statusChange(ele.id)"
|
||||
>{{ $t(ele.label) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="filter">
|
||||
<span>{{ $t("commons.organization") }}</span>
|
||||
<div class="filter-item">
|
||||
<span
|
||||
v-for="ele in selectDeptsCahe"
|
||||
:key="ele.id"
|
||||
class="item"
|
||||
:class="[activeDept.includes(ele.id) ? 'active' : '']"
|
||||
@click="activeDeptChange(ele.id)"
|
||||
>{{ ele.label }}</span>
|
||||
<el-popover
|
||||
placement="bottom"
|
||||
popper-class="user-popper"
|
||||
width="200"
|
||||
trigger="click"
|
||||
>
|
||||
<el-popover
|
||||
placement="bottom"
|
||||
popper-class="user-popper dept"
|
||||
width="200"
|
||||
trigger="click"
|
||||
>
|
||||
<el-tree
|
||||
:load="loadNode"
|
||||
:lazy="true"
|
||||
:expand-on-click-node="false"
|
||||
:data="deptsComputed"
|
||||
:props="defaultProps"
|
||||
@node-click="handleNodeClick"
|
||||
/>
|
||||
|
||||
<el-select
|
||||
ref="roleSelect"
|
||||
slot="reference"
|
||||
v-model="selectDepts"
|
||||
popper-class="tree-select"
|
||||
multiple
|
||||
:placeholder="$t('commons.please_select')"
|
||||
value-key="id"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in selectDepts"
|
||||
:key="item.label"
|
||||
:label="item.label"
|
||||
:value="item"
|
||||
/>
|
||||
</el-select>
|
||||
</el-popover>
|
||||
<span
|
||||
slot="reference"
|
||||
class="more"
|
||||
>+ {{ $t("panel.more") }}</span>
|
||||
</el-popover>
|
||||
</div>
|
||||
</div>
|
||||
<div class="filter">
|
||||
<span>{{ $t("panel.role") }}</span>
|
||||
<div class="filter-item">
|
||||
<span
|
||||
v-for="ele in rolesValueCopy"
|
||||
:key="ele.id"
|
||||
class="item"
|
||||
:class="[activeRole.includes(ele.id) ? 'active' : '']"
|
||||
@click="activeRoleChange(ele.id)"
|
||||
>{{ ele.name }}</span>
|
||||
<el-popover
|
||||
placement="bottom"
|
||||
popper-class="user-popper"
|
||||
width="200"
|
||||
trigger="click"
|
||||
>
|
||||
<el-select
|
||||
ref="roleSelect"
|
||||
v-model="rolesValue"
|
||||
multiple
|
||||
:placeholder="$t('commons.please_select')"
|
||||
value-key="id"
|
||||
@change="changeRole"
|
||||
@remove-tag="changeRole"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in rolesComputed"
|
||||
:key="item.name"
|
||||
:label="item.name"
|
||||
:value="item"
|
||||
/>
|
||||
</el-select>
|
||||
<span
|
||||
slot="reference"
|
||||
class="more"
|
||||
>+ {{ $t("panel.more") }}</span>
|
||||
</el-popover>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="de-foot">
|
||||
<deBtn
|
||||
secondary
|
||||
@click="reset"
|
||||
>{{
|
||||
$t("commons.reset")
|
||||
}}</deBtn>
|
||||
<deBtn
|
||||
type="primary"
|
||||
@click="search"
|
||||
>{{
|
||||
$t("commons.adv_search.search")
|
||||
}}</deBtn>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { allRoles } from '@/api/system/user'
|
||||
import { getDeptTree, treeByDeptId } from '@/api/system/dept'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
roleCahe: [],
|
||||
deptCahe: [],
|
||||
roles: [],
|
||||
filterTextMap: [],
|
||||
status: [
|
||||
{
|
||||
id: 1,
|
||||
label: 'commons.enable'
|
||||
},
|
||||
{
|
||||
id: 0,
|
||||
label: 'commons.disable'
|
||||
}
|
||||
],
|
||||
activeStatus: [],
|
||||
rolesValue: [],
|
||||
activeRole: [],
|
||||
depts: [],
|
||||
selectDepts: [],
|
||||
selectDeptsCahe: [],
|
||||
activeDept: [],
|
||||
defaultProps: {
|
||||
children: 'children',
|
||||
label: 'label',
|
||||
isLeaf: 'leaf'
|
||||
},
|
||||
userDrawer: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
rolesComputed() {
|
||||
return this.roles.filter((ele) => !this.activeRole.includes(ele.id))
|
||||
},
|
||||
rolesValueCopy() {
|
||||
return this.roleCahe.filter((ele) => this.activeRole.includes(ele.id))
|
||||
},
|
||||
deptsComputed() {
|
||||
return this.depts.filter((ele) => !this.activeDept.includes(ele.id))
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initRoles()
|
||||
},
|
||||
methods: {
|
||||
clearFilter() {
|
||||
Array(3)
|
||||
.fill(1)
|
||||
.forEach((_, index) => {
|
||||
this.clearOneFilter(index)
|
||||
})
|
||||
this.$emit('search', [], [])
|
||||
},
|
||||
clearOneFilter(index) {
|
||||
(this.filterTextMap[index] || []).forEach((ele) => {
|
||||
this[ele] = []
|
||||
})
|
||||
},
|
||||
// 获取弹窗内部门数据
|
||||
treeByDeptId() {
|
||||
treeByDeptId(0).then((res) => {
|
||||
this.depts = (res.data || []).map((ele) => {
|
||||
return {
|
||||
...ele,
|
||||
leaf: !ele.hasChildren
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
changeRole() {
|
||||
if (
|
||||
this.roleCahe.length >
|
||||
this.rolesValue.length + this.activeRole.length
|
||||
) {
|
||||
this.roleCahe = this.roleCahe.filter((ele) =>
|
||||
this.rolesValue
|
||||
.map((ele) => ele.id)
|
||||
.concat(this.activeRole)
|
||||
.includes(ele.id)
|
||||
)
|
||||
return
|
||||
}
|
||||
const roleIdx = this.rolesValue.findIndex(
|
||||
(ele) =>
|
||||
!this.roleCahe
|
||||
.map((ele) => ele.id)
|
||||
.concat(this.activeRole)
|
||||
.includes(ele.id)
|
||||
)
|
||||
if (roleIdx === -1) return
|
||||
this.activeRole.push(this.rolesValue[roleIdx].id)
|
||||
this.roleCahe.push(this.rolesValue[roleIdx])
|
||||
this.rolesValue.splice(roleIdx, 1)
|
||||
},
|
||||
activeRoleChange(id) {
|
||||
const roleIndex = this.activeRole.findIndex((ele) => ele === id)
|
||||
if (roleIndex === -1) {
|
||||
this.activeRole.push(id)
|
||||
this.rolesValue = this.rolesValue.filter((ele) => ele.id !== id)
|
||||
} else {
|
||||
this.activeRole.splice(roleIndex, 1)
|
||||
const role = this.roleCahe.find((ele) => ele.id === id)
|
||||
this.rolesValue.push(role)
|
||||
}
|
||||
},
|
||||
handleNodeClick({ id, label }) {
|
||||
const deptIdx = this.selectDepts.findIndex((ele) => ele.id === id)
|
||||
if (deptIdx !== -1) {
|
||||
this.selectDepts.splice(deptIdx, 1)
|
||||
this.selectDeptsCahe = this.selectDeptsCahe.filter(
|
||||
(ele) => ele.id !== id
|
||||
)
|
||||
this.deptCahe = this.deptCahe.filter((ele) => ele.id !== id)
|
||||
return
|
||||
}
|
||||
this.activeDept.push(id)
|
||||
this.selectDeptsCahe.push({ id, label })
|
||||
this.deptCahe.push({ id, label })
|
||||
},
|
||||
activeDeptChange(id) {
|
||||
const dept = this.deptCahe.find((ele) => ele.id === id)
|
||||
this.selectDepts.push(dept)
|
||||
this.activeDept = this.activeDept.filter((ele) => ele !== id)
|
||||
this.selectDeptsCahe = this.selectDeptsCahe.filter(
|
||||
(ele) => ele.id !== id
|
||||
)
|
||||
},
|
||||
statusChange(id) {
|
||||
const statusIndex = this.activeStatus.findIndex((ele) => ele === id)
|
||||
if (statusIndex === -1) {
|
||||
this.activeStatus.push(id)
|
||||
} else {
|
||||
this.activeStatus.splice(statusIndex, 1)
|
||||
}
|
||||
},
|
||||
changeDepts() {
|
||||
const depts = this.selectDepts.map((item) => item.id)
|
||||
this.activeDept = this.activeDept.filter((ele) => depts.includes(ele))
|
||||
},
|
||||
loadNode(node, resolve) {
|
||||
if (!this.depts.length) {
|
||||
this.treeByDeptId()
|
||||
return
|
||||
}
|
||||
getDeptTree(node.data.id).then((res) => {
|
||||
const filterDept = (res.data || []).filter(
|
||||
(ele) => !this.activeDept.includes(ele.deptId)
|
||||
)
|
||||
resolve(
|
||||
filterDept.map((dept) => {
|
||||
return this.normalizer(dept)
|
||||
})
|
||||
)
|
||||
})
|
||||
},
|
||||
normalizer(node) {
|
||||
return {
|
||||
id: node.deptId,
|
||||
label: node.name,
|
||||
leaf: !node.hasChildren
|
||||
}
|
||||
},
|
||||
initRoles() {
|
||||
allRoles().then((res) => {
|
||||
this.roles = res.data
|
||||
})
|
||||
},
|
||||
search() {
|
||||
this.userDrawer = false
|
||||
this.$emit('search', this.formatCondition(), this.formatText())
|
||||
},
|
||||
formatText() {
|
||||
this.filterTextMap = []
|
||||
const params = []
|
||||
if (this.activeStatus.length) {
|
||||
const str = `${this.$t('kettle.status')}:${this.activeStatus.reduce(
|
||||
(pre, next) =>
|
||||
this.$t((this.status.find((ele) => ele.id === next) || {}).label) +
|
||||
'、' +
|
||||
pre,
|
||||
''
|
||||
)}`
|
||||
params.push(str.slice(0, str.length - 1))
|
||||
this.filterTextMap.push(['activeStatus'])
|
||||
}
|
||||
if (this.activeDept.length) {
|
||||
params.push(
|
||||
`${this.$t('panel.org')}:${this.selectDeptsCahe
|
||||
.map((ele) => ele.label)
|
||||
.join('、')}`
|
||||
)
|
||||
this.filterTextMap.push([
|
||||
'activeDept',
|
||||
'selectDepts',
|
||||
'selectDeptsCahe',
|
||||
'deptCahe'
|
||||
])
|
||||
}
|
||||
if (this.activeRole.length) {
|
||||
params.push(
|
||||
`${this.$t('panel.role')}:${this.rolesValueCopy
|
||||
.map((ele) => ele.name)
|
||||
.join('、')}`
|
||||
)
|
||||
this.filterTextMap.push(['rolesValue', 'activeRole', 'roleCahe'])
|
||||
}
|
||||
return params
|
||||
},
|
||||
formatCondition() {
|
||||
const fildMap = {
|
||||
'r.role_id': this.activeRole,
|
||||
'd.dept_id': this.activeDept,
|
||||
'u.enabled': this.activeStatus
|
||||
}
|
||||
const conditions = []
|
||||
Object.keys(fildMap).forEach((ele) => {
|
||||
if (fildMap[ele].length) {
|
||||
conditions.push({
|
||||
field: ele,
|
||||
operator: 'in',
|
||||
value: fildMap[ele]
|
||||
})
|
||||
}
|
||||
})
|
||||
return conditions
|
||||
},
|
||||
init() {
|
||||
this.userDrawer = true
|
||||
},
|
||||
reset() {
|
||||
this.userDrawer = false
|
||||
this.clearFilter()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
144
frontend/src/views/system/user/PersonPwd.vue
Normal file
144
frontend/src/views/system/user/PersonPwd.vue
Normal file
@ -0,0 +1,144 @@
|
||||
<template>
|
||||
<layout-content>
|
||||
<div style="width: 100%;display: flex;justify-content: center;">
|
||||
<el-card class="box-card about-card">
|
||||
<div class="form-header">
|
||||
<span>{{ $t('user.change_password') }}</span>
|
||||
</div>
|
||||
<el-form
|
||||
ref="createUserForm"
|
||||
:model="form"
|
||||
:rules="rule"
|
||||
size="small"
|
||||
label-width="auto"
|
||||
label-position="right"
|
||||
>
|
||||
<el-form-item
|
||||
:label="$t('user.origin_passwd')"
|
||||
prop="oldPwd"
|
||||
>
|
||||
<dePwd
|
||||
v-model="form.oldPwd"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="$t('user.new_passwd')"
|
||||
prop="newPwd"
|
||||
>
|
||||
<dePwd
|
||||
v-model="form.newPwd"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="$t('user.confirm_passwd')"
|
||||
prop="repeatPwd"
|
||||
>
|
||||
<dePwd
|
||||
v-model="form.repeatPwd"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="save"
|
||||
>{{ $t('commons.confirm') }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</layout-content>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LayoutContent from '@/components/business/LayoutContent'
|
||||
import { updatePersonPwd } from '@/api/system/user'
|
||||
import dePwd from '@/components/deCustomCm/dePwd.vue'
|
||||
export default {
|
||||
|
||||
components: { LayoutContent, dePwd },
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
|
||||
},
|
||||
rule: {
|
||||
|
||||
oldPwd: [
|
||||
{ required: true, message: this.$t('user.input_password'), trigger: 'blur' }
|
||||
],
|
||||
newPwd: [
|
||||
{ required: true, message: this.$t('user.input_password'), trigger: 'blur' },
|
||||
{
|
||||
required: true,
|
||||
pattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[^]{8,30}$/,
|
||||
message: this.$t('member.password_format_is_incorrect'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
repeatPwd: [
|
||||
{ required: true, message: this.$t('user.input_password'), trigger: 'blur' },
|
||||
{ required: true, trigger: 'blur', validator: this.repeatValidator }
|
||||
]
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.$store.dispatch('app/toggleSideBarHide', true)
|
||||
})
|
||||
},
|
||||
created() {
|
||||
this.$store.dispatch('app/toggleSideBarHide', true)
|
||||
},
|
||||
methods: {
|
||||
repeatValidator(rule, value, callback) {
|
||||
if (value !== this.form.newPwd) {
|
||||
callback(new Error(this.$t('member.inconsistent_passwords')))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
|
||||
save() {
|
||||
this.$refs.createUserForm.validate(valid => {
|
||||
if (valid) {
|
||||
const param = {
|
||||
password: this.form.oldPwd,
|
||||
newPassword: this.form.newPwd
|
||||
}
|
||||
updatePersonPwd(param).then(res => {
|
||||
this.$success(this.$t('commons.save_success'))
|
||||
this.logout()
|
||||
})
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
async logout() {
|
||||
await this.$store.dispatch('user/logout')
|
||||
this.$router.push('/')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.about-card {
|
||||
background: inherit;
|
||||
margin-top: 5%;
|
||||
flex-direction: row;
|
||||
width: 640px;
|
||||
min-width: 640px;
|
||||
height: auto;
|
||||
position: relative;
|
||||
::v-deep div.el-card__header {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
.form-header {
|
||||
line-height: 60px;
|
||||
font-size: 18px;
|
||||
}
|
||||
</style>
|
386
frontend/src/views/system/user/PrivateForm.vue
Normal file
386
frontend/src/views/system/user/PrivateForm.vue
Normal file
@ -0,0 +1,386 @@
|
||||
<template>
|
||||
<layout-content>
|
||||
<div style="width: 100%;display: flex;justify-content: center;">
|
||||
<el-card class="box-card about-card">
|
||||
<div class="form-header">
|
||||
<span>{{ $t('commons.personal_info') }}</span>
|
||||
</div>
|
||||
<el-form
|
||||
ref="createUserForm"
|
||||
:model="form"
|
||||
:rules="rule"
|
||||
size="small"
|
||||
label-width="auto"
|
||||
label-position="right"
|
||||
>
|
||||
<el-form-item
|
||||
label="ID"
|
||||
prop="username"
|
||||
>
|
||||
<el-input
|
||||
v-model="form.username"
|
||||
disabled
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="$t('commons.phone')"
|
||||
prop="phone"
|
||||
>
|
||||
<el-input
|
||||
v-model="form.phone"
|
||||
:disabled="formType!=='modify'"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="$t('commons.nick_name')"
|
||||
prop="nickName"
|
||||
>
|
||||
<el-input
|
||||
v-model="form.nickName"
|
||||
:disabled="formType!=='modify'"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="$t('commons.email')"
|
||||
prop="email"
|
||||
>
|
||||
<el-input
|
||||
v-model="form.email"
|
||||
:disabled="formType!=='modify'"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('commons.status')">
|
||||
<el-radio-group
|
||||
v-model="form.enabled"
|
||||
disabled
|
||||
style="width: 140px"
|
||||
>
|
||||
<el-radio :label="1">{{ $t('commons.enable') }}</el-radio>
|
||||
<el-radio :label="0">{{ $t('commons.disable') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
disabled
|
||||
:label="$t('commons.organization')"
|
||||
prop="dept"
|
||||
>
|
||||
<treeselect
|
||||
v-model="form.deptId"
|
||||
disabled
|
||||
:options="depts"
|
||||
:load-options="loadDepts"
|
||||
:auto-load-root-options="false"
|
||||
:placeholder="$t('user.choose_org')"
|
||||
:no-children-text="$t('commons.treeselect.no_children_text')"
|
||||
:no-options-text="$t('commons.treeselect.no_options_text')"
|
||||
:no-results-text="$t('commons.treeselect.no_results_text')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
:label="$t('commons.role')"
|
||||
prop="roleIds"
|
||||
>
|
||||
<el-select
|
||||
v-model="form.roleIds"
|
||||
disabled
|
||||
style="width: 100%"
|
||||
multiple
|
||||
:placeholder="$t('commons.please_select')"
|
||||
@remove-tag="deleteTag"
|
||||
@change="changeRole"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in roles"
|
||||
:key="item.name"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<plugin-com
|
||||
v-if="isPluginLoaded"
|
||||
ref="AuthenticationBind"
|
||||
:user-id="form.userId"
|
||||
:form-type="formType"
|
||||
component-name="AuthenticationBind"
|
||||
/>
|
||||
|
||||
<!--提供修改个人电话,邮箱和昵称的功能-->
|
||||
<el-form-item v-if="formType!=='modify'">
|
||||
<el-button @click="formType = 'modify'">修改个人信息</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item v-else>
|
||||
<el-button
|
||||
v-if="formType==='modify'"
|
||||
type="primary"
|
||||
@click="save"
|
||||
>保存</el-button>
|
||||
<el-button
|
||||
v-if="formType==='modify'"
|
||||
@click="reset"
|
||||
>取消</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<div
|
||||
slot="footer"
|
||||
style="margin-left: 30px;"
|
||||
class="dialog-footer"
|
||||
>
|
||||
<el-button
|
||||
v-if="formType==='modify'"
|
||||
type="text"
|
||||
@click="reset"
|
||||
>{{ $t('commons.cancel') }}</el-button>
|
||||
<el-button
|
||||
v-if="formType==='modify'"
|
||||
type="primary"
|
||||
@click="save"
|
||||
>{{ $t('commons.confirm') }}</el-button>
|
||||
<el-button
|
||||
v-if="formType!=='modify'"
|
||||
type="primary"
|
||||
@click="edit"
|
||||
>{{ $t('commons.edit') }}</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
</layout-content>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LayoutContent from '@/components/business/LayoutContent'
|
||||
import Treeselect from '@riophae/vue-treeselect'
|
||||
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
|
||||
import { PHONE_REGEX } from '@/utils/validate'
|
||||
import { LOAD_CHILDREN_OPTIONS, LOAD_ROOT_OPTIONS } from '@riophae/vue-treeselect'
|
||||
import { getDeptTree, treeByDeptId } from '@/api/system/dept'
|
||||
import { allRoles } from '@/api/system/user'
|
||||
import { updatePerson, personInfo } from '@/api/system/user'
|
||||
import { pluginLoaded } from '@/api/user'
|
||||
import PluginCom from '@/views/system/plugin/PluginCom'
|
||||
import Cookies from 'js-cookie'
|
||||
export default {
|
||||
components: { LayoutContent, Treeselect, PluginCom },
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
roles: [{
|
||||
id: ''
|
||||
}]
|
||||
},
|
||||
rule: {
|
||||
username: [
|
||||
{ required: true, message: this.$t('user.input_id'), trigger: 'blur' },
|
||||
{ min: 1, max: 50, message: this.$t('commons.input_limit', [1, 50]), trigger: 'blur' },
|
||||
{
|
||||
required: true,
|
||||
pattern: '^[^\u4e00-\u9fa5]+$',
|
||||
message: this.$t('user.special_characters_are_not_supported'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
nickName: [
|
||||
{ required: true, message: this.$t('user.input_name'), trigger: 'blur' },
|
||||
{ min: 2, max: 50, message: this.$t('commons.input_limit', [2, 50]), trigger: 'blur' },
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('user.special_characters_are_not_supported'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
phone: [
|
||||
{
|
||||
pattern: PHONE_REGEX,
|
||||
message: this.$t('user.mobile_number_format_is_incorrect'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
email: [
|
||||
{ required: true, message: this.$t('user.input_email'), trigger: 'blur' },
|
||||
{
|
||||
required: true,
|
||||
pattern: /^[a-zA-Z0-9_._-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/,
|
||||
message: this.$t('user.email_format_is_incorrect'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
password: [
|
||||
{ required: true, message: this.$t('user.input_password'), trigger: 'blur' },
|
||||
{
|
||||
required: true,
|
||||
pattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[^]{8,30}$/,
|
||||
message: this.$t('member.password_format_is_incorrect'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
newPassword: [
|
||||
{ required: true, message: this.$t('user.input_password'), trigger: 'blur' },
|
||||
{
|
||||
required: true,
|
||||
pattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[^]{8,30}$/,
|
||||
message: this.$t('member.password_format_is_incorrect'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
},
|
||||
defaultForm: { id: null, username: null, nickName: null, gender: '男', email: null, enabled: 1, deptId: null, phone: null, roleIds: [] },
|
||||
depts: null,
|
||||
roles: [],
|
||||
roleDatas: [],
|
||||
userRoles: [],
|
||||
formType: 'add',
|
||||
isPluginLoaded: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.$store.dispatch('app/toggleSideBarHide', true)
|
||||
})
|
||||
},
|
||||
created() {
|
||||
this.$store.dispatch('app/toggleSideBarHide', true)
|
||||
this.showError()
|
||||
this.queryPerson()
|
||||
this.initRoles()
|
||||
},
|
||||
beforeCreate() {
|
||||
pluginLoaded().then(res => {
|
||||
this.isPluginLoaded = res.success && res.data
|
||||
}).catch(() => {
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
showError() {
|
||||
const errKeys = ['WecomError', 'DingtalkError', 'LarkError']
|
||||
errKeys.forEach(key => {
|
||||
const msg = Cookies.get(key)
|
||||
if (msg) {
|
||||
this.$error(msg)
|
||||
Cookies.remove(key)
|
||||
}
|
||||
})
|
||||
},
|
||||
queryPerson() {
|
||||
personInfo().then(res => {
|
||||
const info = res.data
|
||||
this.form = info
|
||||
const roles = info.roles
|
||||
this.form['roleIds'] = roles.map(role => role.id)
|
||||
if (this.form.deptId === 0) {
|
||||
this.form.deptId = null
|
||||
}
|
||||
this.initDeptTree()
|
||||
})
|
||||
},
|
||||
edit() {
|
||||
this.formType = 'modify'
|
||||
},
|
||||
initRoles() {
|
||||
allRoles().then(res => {
|
||||
this.roles = res.data
|
||||
})
|
||||
},
|
||||
initDeptTree() {
|
||||
treeByDeptId(this.form.deptId || 0).then(res => {
|
||||
const results = res.data.map(node => {
|
||||
if (node.hasChildren && !node.children) {
|
||||
node.children = null
|
||||
// delete node.children
|
||||
}
|
||||
return node
|
||||
})
|
||||
this.depts = results
|
||||
})
|
||||
},
|
||||
// 获取弹窗内部门数据
|
||||
loadDepts({ action, parentNode, callback }) {
|
||||
if (action === LOAD_ROOT_OPTIONS && !this.form.deptId) {
|
||||
const _self = this
|
||||
treeByDeptId(0).then(res => {
|
||||
const results = res.data.map(node => {
|
||||
if (node.hasChildren && !node.children) {
|
||||
node.children = null
|
||||
}
|
||||
return node
|
||||
})
|
||||
_self.depts = results
|
||||
callback()
|
||||
})
|
||||
}
|
||||
if (action === LOAD_CHILDREN_OPTIONS) {
|
||||
const _self = this
|
||||
getDeptTree(parentNode.id).then(res => {
|
||||
parentNode.children = res.data.map(function(obj) {
|
||||
return _self.normalizer(obj)
|
||||
})
|
||||
callback()
|
||||
})
|
||||
}
|
||||
},
|
||||
normalizer(node) {
|
||||
if (node.hasChildren) {
|
||||
node.children = null
|
||||
}
|
||||
return {
|
||||
id: node.deptId,
|
||||
label: node.name,
|
||||
children: node.children
|
||||
}
|
||||
},
|
||||
deleteTag(value) {
|
||||
this.userRoles.forEach(function(data, index) {
|
||||
if (data.id === value) {
|
||||
this.userRoles.splice(index, value)
|
||||
}
|
||||
}.bind(this))
|
||||
},
|
||||
changeRole(value) {
|
||||
this.userRoles = []
|
||||
value.forEach(function(data, index) {
|
||||
const role = { id: data }
|
||||
this.userRoles.push(role)
|
||||
}.bind(this))
|
||||
},
|
||||
reset() {
|
||||
this.formType = 'add'
|
||||
this.queryPerson()
|
||||
// 清空表单提示
|
||||
this.$refs.createUserForm.clearValidate()
|
||||
},
|
||||
save() {
|
||||
this.$refs.createUserForm.validate(valid => {
|
||||
if (valid) {
|
||||
updatePerson(this.form).then(res => {
|
||||
this.$success(this.$t('commons.save_success'))
|
||||
this.reset()
|
||||
})
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.about-card {
|
||||
background: inherit;
|
||||
margin-top: 5%;
|
||||
flex-direction: row;
|
||||
width: 640px;
|
||||
min-width: 640px;
|
||||
height: auto;
|
||||
position: relative;
|
||||
::v-deep div.el-card__header {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
.form-header {
|
||||
line-height: 60px;
|
||||
font-size: 18px;
|
||||
}
|
||||
</style>
|
651
frontend/src/views/system/user/UserEditer.vue
Normal file
651
frontend/src/views/system/user/UserEditer.vue
Normal file
@ -0,0 +1,651 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:title="formType == 'add' ? $t('user.create') : $t('user.modify')"
|
||||
:visible.sync="dialogVisible"
|
||||
class="user-editer-form"
|
||||
width="840px"
|
||||
:before-close="reset"
|
||||
>
|
||||
<div
|
||||
v-if="formType === 'add'"
|
||||
class="editer-form-title"
|
||||
>
|
||||
<i class="el-icon-info" />
|
||||
<span
|
||||
class="pwd"
|
||||
type="text"
|
||||
>{{
|
||||
$t("commons.default_pwd") + ":" + defaultPWD
|
||||
}}</span>
|
||||
<el-button
|
||||
v-clipboard:copy="defaultPWD"
|
||||
v-clipboard:success="onCopy"
|
||||
v-clipboard:error="onError"
|
||||
class="btn-text"
|
||||
type="text"
|
||||
>
|
||||
{{ $t("commons.copy") }}
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<el-form
|
||||
ref="createUserForm"
|
||||
:model="form"
|
||||
:rules="rule"
|
||||
size="small"
|
||||
label-width="80px"
|
||||
label-position="right"
|
||||
>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<el-form-item
|
||||
:label="$t('commons.nick_name')"
|
||||
prop="nickName"
|
||||
>
|
||||
<el-input
|
||||
v-model="form.nickName"
|
||||
:placeholder="$t('user.input_name')"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item
|
||||
label="ID"
|
||||
prop="username"
|
||||
>
|
||||
<el-input
|
||||
v-model="form.username"
|
||||
:placeholder="$t('user.input_id')"
|
||||
:disabled="formType !== 'add'"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<el-form-item
|
||||
:label="$t('commons.email')"
|
||||
prop="email"
|
||||
>
|
||||
<el-input
|
||||
v-model="form.email"
|
||||
:placeholder="$t('user.input_email')"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item
|
||||
:label="$t('commons.mobile_phone_number')"
|
||||
prop="phone"
|
||||
>
|
||||
<el-input
|
||||
v-model="form.phone"
|
||||
:placeholder="$t('commons.mobile_phone')"
|
||||
class="input-with-select"
|
||||
>
|
||||
<el-select
|
||||
slot="prepend"
|
||||
v-model="form.phonePrefix"
|
||||
:placeholder="$t('fu.search_bar.please_select')"
|
||||
>
|
||||
<el-option
|
||||
label="+86"
|
||||
value="+86"
|
||||
/>
|
||||
</el-select>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<el-form-item
|
||||
:label="$t('commons.gender')"
|
||||
prop="gender"
|
||||
>
|
||||
<el-select
|
||||
v-model="form.gender"
|
||||
class="form-gender-select"
|
||||
:placeholder="$t('user.select_gender')"
|
||||
>
|
||||
<el-option
|
||||
:label="$t('commons.man')"
|
||||
value="男"
|
||||
/>
|
||||
<el-option
|
||||
:label="$t('commons.woman')"
|
||||
value="女"
|
||||
/>
|
||||
<el-option
|
||||
:label="$t('commons.keep_secret')"
|
||||
value="保密"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item
|
||||
v-show="isPluginLoaded"
|
||||
:label="$t('commons.organization')"
|
||||
prop="deptId"
|
||||
>
|
||||
<el-popover
|
||||
placement="bottom"
|
||||
popper-class="user-popper dept"
|
||||
width="384"
|
||||
trigger="click"
|
||||
>
|
||||
<el-tree
|
||||
v-if="dialogVisible"
|
||||
:load="loadNode"
|
||||
:lazy="true"
|
||||
:expand-on-click-node="false"
|
||||
:data="depts"
|
||||
:props="defaultProps"
|
||||
@node-click="handleNodeClick"
|
||||
/>
|
||||
|
||||
<el-select
|
||||
ref="roleSelect"
|
||||
slot="reference"
|
||||
v-model="form.deptId"
|
||||
clearable
|
||||
class="form-gender-select"
|
||||
popper-class="tree-select"
|
||||
:placeholder="$t('commons.please_select')"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in selectDepts"
|
||||
:key="item.label"
|
||||
:label="item.label"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-popover>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-form-item
|
||||
v-show="isPluginLoaded"
|
||||
:label="$t('commons.role')"
|
||||
prop="roleIds"
|
||||
>
|
||||
<el-select
|
||||
ref="roleSelect"
|
||||
v-model="form.roleIds"
|
||||
style="width: 100%"
|
||||
:disabled="formType !== 'add' && form.isAdmin"
|
||||
multiple
|
||||
:placeholder="$t('user.input_roles')"
|
||||
@remove-tag="deleteTag"
|
||||
@change="changeRole"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in roles"
|
||||
:key="item.name"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item
|
||||
:label="$t('commons.status')"
|
||||
prop="enabled"
|
||||
>
|
||||
<el-switch
|
||||
v-model="form.enabled"
|
||||
:disabled="formType !== 'add' && form.isAdmin"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span
|
||||
slot="footer"
|
||||
class="dialog-footer"
|
||||
>
|
||||
<deBtn
|
||||
secondary
|
||||
@click="reset"
|
||||
>{{
|
||||
$t("commons.cancel")
|
||||
}}</deBtn>
|
||||
<deBtn
|
||||
type="primary"
|
||||
@click="save"
|
||||
>{{
|
||||
$t("commons.confirm")
|
||||
}}</deBtn>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { PHONE_REGEX } from '@/utils/validate'
|
||||
import { getDeptTree, treeByDeptId } from '@/api/system/dept'
|
||||
import { addUser, editUser, allRoles, queryAssist } from '@/api/system/user'
|
||||
import { pluginLoaded, defaultPwd, wecomStatus, dingtalkStatus, larkStatus } from '@/api/user'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
defaultProps: {
|
||||
children: 'children',
|
||||
label: 'label',
|
||||
isLeaf: 'leaf'
|
||||
},
|
||||
selectDepts: [],
|
||||
form: {
|
||||
roles: [
|
||||
{
|
||||
id: ''
|
||||
}
|
||||
],
|
||||
sysUserAssist: {
|
||||
wecomId: null,
|
||||
dingtalkId: null,
|
||||
larkId: null
|
||||
}
|
||||
},
|
||||
rule: {
|
||||
username: [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('user.id_mandatory'),
|
||||
trigger: 'blur'
|
||||
},
|
||||
{
|
||||
min: 1,
|
||||
max: 50,
|
||||
message: this.$t('commons.input_limit', [1, 50]),
|
||||
trigger: 'blur'
|
||||
},
|
||||
{
|
||||
required: true,
|
||||
pattern: '^[^\u4e00-\u9fa5]+$',
|
||||
message: this.$t('user.special_characters_are_not_supported'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
nickName: [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('user.name_mandatory'),
|
||||
trigger: 'blur'
|
||||
},
|
||||
{
|
||||
min: 2,
|
||||
max: 50,
|
||||
message: this.$t('commons.input_limit', [2, 50]),
|
||||
trigger: 'blur'
|
||||
},
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('user.special_characters_are_not_supported'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
phone: [
|
||||
{
|
||||
pattern: PHONE_REGEX,
|
||||
message: this.$t('user.phone_format'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
email: [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('user.email_mandatory'),
|
||||
trigger: 'blur'
|
||||
},
|
||||
{
|
||||
required: true,
|
||||
pattern: /^[a-zA-Z0-9_._-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/,
|
||||
message: this.$t('user.email_format_is_incorrect'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
password: [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('user.input_password'),
|
||||
trigger: 'blur'
|
||||
},
|
||||
{
|
||||
required: true,
|
||||
pattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[^]{8,30}$/,
|
||||
message: this.$t('member.password_format_is_incorrect'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
confirmPassword: [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('user.input_password'),
|
||||
trigger: 'blur'
|
||||
},
|
||||
{ required: true, validator: this.repeatValidator, trigger: 'blur' }
|
||||
],
|
||||
newPassword: [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('user.input_password'),
|
||||
trigger: 'blur'
|
||||
},
|
||||
{
|
||||
required: true,
|
||||
pattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[^]{8,30}$/,
|
||||
message: this.$t('member.password_format_is_incorrect'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
deptId: [],
|
||||
gender: [],
|
||||
enabled: [{ required: true, trigger: 'change' }]
|
||||
},
|
||||
defaultForm: {
|
||||
id: null,
|
||||
username: null,
|
||||
nickName: null,
|
||||
gender: '男',
|
||||
email: null,
|
||||
enabled: 1,
|
||||
deptId: null,
|
||||
phone: null,
|
||||
phonePrefix: '+86',
|
||||
roleIds: [2],
|
||||
sysUserAssist: {
|
||||
wecomId: null,
|
||||
dingtalkId: null,
|
||||
larkId: null
|
||||
}
|
||||
},
|
||||
depts: [],
|
||||
roles: [],
|
||||
roleDatas: [],
|
||||
userRoles: [],
|
||||
formType: 'add',
|
||||
isPluginLoaded: false,
|
||||
defaultPWD: 'DataEase123..',
|
||||
dialogVisible: false,
|
||||
wecomOpen: false,
|
||||
dingTalkOpen: false,
|
||||
larkOpen: false,
|
||||
assistInfo: {}
|
||||
}
|
||||
},
|
||||
beforeCreate() {
|
||||
pluginLoaded().then((res) => {
|
||||
this.isPluginLoaded = res.success && res.data
|
||||
})
|
||||
wecomStatus().then(res => {
|
||||
if (res.success && res.data) {
|
||||
this.wecomOpen = true
|
||||
}
|
||||
})
|
||||
|
||||
dingtalkStatus().then(res => {
|
||||
if (res.success && res.data) {
|
||||
this.dingTalkOpen = true
|
||||
}
|
||||
})
|
||||
|
||||
larkStatus().then(res => {
|
||||
if (res.success && res.data) {
|
||||
this.larkOpen = true
|
||||
}
|
||||
})
|
||||
defaultPwd().then((res) => {
|
||||
if (res && res.data) {
|
||||
this.defaultPWD = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
repeatValidator(rule, value, callback) {
|
||||
if (value !== this.form.password) {
|
||||
callback(new Error(this.$t('member.inconsistent_passwords')))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
create() {
|
||||
this.formType = 'add'
|
||||
this.form = Object.assign({}, JSON.parse(JSON.stringify(this.defaultForm)))
|
||||
},
|
||||
init(row) {
|
||||
this.initRoles()
|
||||
|
||||
this.dialogVisible = true
|
||||
if (!row) {
|
||||
this.create()
|
||||
return
|
||||
}
|
||||
this.initAssistInfo(row.userId).then(res => {
|
||||
this.assistInfo = res.data
|
||||
const { deptId: id, deptName: label } = (row.dept || {})
|
||||
this.selectDepts = [{ id, label }]
|
||||
this.formType = 'modify'
|
||||
this.dialogVisible = true
|
||||
row.sysUserAssist = JSON.parse(JSON.stringify(this.defaultForm.sysUserAssist))
|
||||
this.form = Object.assign({}, row)
|
||||
this.form.password = ''
|
||||
if (this.form.deptId === 0) {
|
||||
this.form.deptId = null
|
||||
}
|
||||
|
||||
if (!this.form.phonePrefix) {
|
||||
this.form.phonePrefix = '+86'
|
||||
}
|
||||
|
||||
if (this.assistInfo) {
|
||||
const info = JSON.parse(JSON.stringify(this.assistInfo))
|
||||
delete info.needFirstNoti
|
||||
delete info.userId
|
||||
const assist = Object.assign(JSON.parse(JSON.stringify(this.defaultForm.sysUserAssist)), info)
|
||||
this.form.sysUserAssist = assist
|
||||
}
|
||||
})
|
||||
},
|
||||
initRoles() {
|
||||
allRoles().then((res) => {
|
||||
this.roles = res.data
|
||||
})
|
||||
},
|
||||
initAssistInfo(userId) {
|
||||
return queryAssist(userId)
|
||||
},
|
||||
handleNodeClick({ id, label }) {
|
||||
const [dept] = this.selectDepts
|
||||
if (!dept || dept.id !== id) {
|
||||
this.selectDepts = [{ id, label }]
|
||||
this.form.deptId = id
|
||||
return
|
||||
}
|
||||
|
||||
if (dept.id === id) {
|
||||
this.selectDepts = []
|
||||
this.form.deptId = null
|
||||
}
|
||||
},
|
||||
// 获取弹窗内部门数据
|
||||
treeByDeptId() {
|
||||
treeByDeptId(0).then((res) => {
|
||||
this.depts = (res.data || []).map(ele => {
|
||||
return {
|
||||
...ele,
|
||||
leaf: !ele.hasChildren
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
loadNode(node, resolve) {
|
||||
if (!this.depts.length) {
|
||||
this.treeByDeptId()
|
||||
return
|
||||
}
|
||||
getDeptTree(node.data.id).then((res) => {
|
||||
resolve(
|
||||
res.data.map((dept) => {
|
||||
return this.normalizer(dept)
|
||||
})
|
||||
)
|
||||
})
|
||||
},
|
||||
normalizer(node) {
|
||||
return {
|
||||
id: node.deptId,
|
||||
label: node.name,
|
||||
leaf: !node.hasChildren
|
||||
}
|
||||
},
|
||||
deleteTag(value) {
|
||||
this.userRoles.forEach(
|
||||
function(data, index) {
|
||||
if (data.id === value) {
|
||||
this.userRoles.splice(index, value)
|
||||
}
|
||||
}.bind(this)
|
||||
)
|
||||
},
|
||||
changeRole(value) {
|
||||
this.userRoles = []
|
||||
value.forEach(
|
||||
function(data, index) {
|
||||
const role = { id: data }
|
||||
this.userRoles.push(role)
|
||||
}.bind(this)
|
||||
)
|
||||
},
|
||||
reset() {
|
||||
this.depts = []
|
||||
this.form.sysUserAssist = JSON.parse(JSON.stringify(this.defaultForm.sysUserAssist))
|
||||
this.$refs.createUserForm.resetFields()
|
||||
this.dialogVisible = false
|
||||
},
|
||||
save() {
|
||||
this.$refs.createUserForm.validate((valid) => {
|
||||
if (valid) {
|
||||
// !this.form.deptId && (this.form.deptId = 0)
|
||||
const method = this.formType === 'add' ? addUser : editUser
|
||||
method(this.form).then((res) => {
|
||||
this.$success(this.$t('commons.save_success'))
|
||||
this.reset()
|
||||
this.$emit('saved')
|
||||
})
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
onCopy(e) {
|
||||
this.$success(this.$t('commons.copy_success'))
|
||||
},
|
||||
onError(e) {}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.user-editer-form {
|
||||
::v-deep .el-dialog__body {
|
||||
padding: 0 24px 24px 24px;
|
||||
}
|
||||
|
||||
::v-deep .el-dialog__header {
|
||||
padding: 24px 24px 16px 24px;
|
||||
}
|
||||
|
||||
::v-deep .el-dialog__footer {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.editer-form-title {
|
||||
width: 100%;
|
||||
border-radius: 4px;
|
||||
background: #e1eaff;
|
||||
padding: 9px 16px;
|
||||
margin-bottom: 16px;
|
||||
|
||||
i {
|
||||
color: #3370ff;
|
||||
font-size: 14.666666030883789px;
|
||||
}
|
||||
|
||||
.pwd,
|
||||
.btn-text {
|
||||
font-family: PingFang SC;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 22px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.pwd {
|
||||
margin: 0 8px;
|
||||
color: #1f2329;
|
||||
}
|
||||
|
||||
.btn-text {
|
||||
padding: 0;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .el-form-item__label {
|
||||
width: 100% !important;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
::v-deep
|
||||
.el-form-item.is-required:not(.is-no-asterisk)
|
||||
> .el-form-item__label:before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
::v-deep
|
||||
.el-form-item.is-required:not(.is-no-asterisk)
|
||||
> .el-form-item__label::after {
|
||||
content: "*";
|
||||
color: #f54a45;
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
::v-deep .el-form-item__content {
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
|
||||
.input-with-select {
|
||||
::v-deep .el-input-group__prepend {
|
||||
background-color: #fff;
|
||||
}
|
||||
.el-select {
|
||||
::v-deep .el-input__inner {
|
||||
width: 72px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-gender-select {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
<style lang="scss">
|
||||
.tree-select {
|
||||
display: none !important;
|
||||
}
|
||||
.user-popper {
|
||||
background: #fff;
|
||||
padding: 0;
|
||||
.popper__arrow {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.user-popper.dept {
|
||||
height: 300px;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
@ -133,7 +133,6 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// import bus from '@/utils/bus'
|
||||
import { allRoles } from '@/api/system/user'
|
||||
import { getDeptTree, treeByDeptId } from '@/api/system/dept'
|
||||
|
||||
|
@ -319,7 +319,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import userEditer from './userEditer.vue'
|
||||
import userEditer from './UserEditer.vue'
|
||||
import { columnOptions } from './options'
|
||||
import DeLayoutContent from '@/components/business/DeLayoutContent'
|
||||
import { addOrder, formatOrders } from '@/utils/index'
|
||||
@ -335,7 +335,7 @@ import {
|
||||
unLock
|
||||
} from '@/api/system/user'
|
||||
import { mapGetters } from 'vuex'
|
||||
import filterUser from './filterUser.vue'
|
||||
import filterUser from './FilterUser.vue'
|
||||
import GridTable from '@/components/gridTable/index.vue'
|
||||
import PluginCom from '@/views/system/plugin/PluginCom'
|
||||
import _ from 'lodash'
|
||||
|
@ -1,6 +1,4 @@
|
||||
<template>
|
||||
<!-- <layout-content :header="formType=='add' ? $t('user.create') : $t('user.modify')" back-name="system-user">
|
||||
</layout-content> -->
|
||||
<el-dialog
|
||||
:title="formType == 'add' ? $t('user.create') : $t('user.modify')"
|
||||
:visible.sync="dialogVisible"
|
||||
@ -168,12 +166,6 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- <el-form-item v-if="formType !== 'modify'" :label="$t('commons.password')" prop="password">
|
||||
<el-input v-model="form.password" autocomplete="off" show-password />
|
||||
</el-form-item>
|
||||
<el-form-item v-if="formType !== 'modify'" :label="$t('commons.confirmPassword')" prop="confirmPassword">
|
||||
<el-input v-model="form.confirmPassword" autocomplete="off" show-password />
|
||||
</el-form-item> -->
|
||||
<el-form-item
|
||||
v-show="isPluginLoaded"
|
||||
:label="$t('commons.role')"
|
||||
|
Loading…
Reference in New Issue
Block a user