Merge remote-tracking branch 'origin/main' into main

This commit is contained in:
wangjiahao
2021-05-31 11:20:43 +08:00
70 changed files with 1914 additions and 219 deletions

View File

@@ -0,0 +1,22 @@
import request from '@/utils/request'
export function get(url) {
return request({
url: url,
method: 'get'
})
}
export function execute(options) {
if (!options || !options.url) {
return null
}
options.type = options.type || 'post'
return request({
url: options.url,
method: options.type,
loading: true,
data: options.data
})
}

View File

@@ -1,6 +1,7 @@
import request from '@/utils/request'
const pathMap = {
queryPath: '/api/plugin/pluginGrid/'
queryPath: '/api/plugin/pluginGrid/',
uninstallPath: 'api/plugin/uninstall/'
}
export function pluginLists(page, size, data) {
return request({
@@ -11,3 +12,11 @@ export function pluginLists(page, size, data) {
})
}
export function uninstall(pluginId) {
return request({
url: pathMap.queryPath + pluginId,
method: 'post',
loading: true
})
}

View File

@@ -7,7 +7,9 @@
</template>
<script>
import Axios from 'axios'
// import Axios from 'axios'
import { get } from '@/api/system/dynamic'
export default {
name: 'AsyncComponent',
@@ -36,13 +38,15 @@ export default {
}
let res
if (!window.SyncComponentCache[this.url]) {
window.SyncComponentCache[this.url] = Axios.get(this.url)
window.SyncComponentCache[this.url] = get(this.url)
// window.SyncComponentCache[this.url] = Axios.get(this.url)
res = await window.SyncComponentCache[this.url]
} else {
res = await window.SyncComponentCache[this.url]
}
const Fn = Function
this.mode = new Fn(`return ${res.data}`)()
this.mode = new Fn(`return ${res.data || res}`)()
}
}
},

View File

@@ -278,7 +278,7 @@ export default {
default_module: 'Default Module'
},
datasource: 'Datasource',
char_can_not_more_50: 'Name can not more 50 char',
char_can_not_more_50: 'Can not more 50 char',
share_success: 'Share Success'
},
documentation: {
@@ -435,7 +435,8 @@ export default {
current_user: 'Current User',
origin_passwd: 'Origin Password',
new_passwd: 'New Password',
confirm_passwd: 'Confirm Password'
confirm_passwd: 'Confirm Password',
change_password: 'Change Password'
},
role: {
menu_authorization: 'Menu Authorization',
@@ -677,7 +678,8 @@ export default {
quota_show: 'Quota Show',
title_limit: 'Title cannot be greater than 50 characters',
filter_condition: 'Filter Condition',
filter_field_can_null: 'Filter field must choose'
filter_field_can_null: 'Filter field must choose',
preview_100_data: 'Preview 100 rows'
},
dataset: {
sheet_warn: 'There are multiple sheet pages, and the first one is extracted by default',
@@ -732,13 +734,13 @@ export default {
error: 'Error',
completed: 'Completed',
underway: 'underway',
task_update: 'Regular update',
task_update: 'Update Setting',
update_type: 'Update Type',
all_scope: 'Full update',
add_scope: 'Incremental update',
select_data_time: 'Select date time',
execute_rate: 'Execution frequency',
execute_once: 'Only once',
execute_once: 'Execution Now',
cron_config: 'Expression setting',
no_limit: 'No limit',
set_end_time: 'Set the end time',

View File

@@ -278,7 +278,7 @@ export default {
default_module: '默认模块'
},
datasource: '數據源',
char_can_not_more_50: '名稱不能超過50字符',
char_can_not_more_50: '不能超過50字符',
share_success: '分享成功'
},
documentation: {
@@ -435,7 +435,8 @@ export default {
current_user: '當前用戶',
origin_passwd: '原始密碼',
new_passwd: '新密碼',
confirm_passwd: '確認密碼'
confirm_passwd: '確認密碼',
change_password: '修改密碼'
},
role: {
menu_authorization: '菜單授權',
@@ -677,7 +678,8 @@ export default {
quota_show: '指標顯示',
title_limit: '標題不能大於50個字符',
filter_condition: '過濾條件',
filter_field_can_null: '過濾字段必填'
filter_field_can_null: '過濾字段必填',
preview_100_data: '預覽前100條記錄'
},
dataset: {
sheet_warn: '有多個sheet頁面默認抽取第一個',
@@ -732,13 +734,13 @@ export default {
error: '錯誤',
completed: '完成',
underway: '執行中',
task_update: '定時更新',
task_update: '更新設置',
update_type: '更新方式',
all_scope: '全量更新',
add_scope: '增量更新',
select_data_time: '選擇日期時間',
execute_rate: '執行頻率',
execute_once: '只執行一次',
execute_once: '立即執行',
cron_config: '表達時設定',
no_limit: '無限制',
set_end_time: '設定結束時間',

View File

@@ -278,7 +278,7 @@ export default {
default_module: '默认模块'
},
datasource: '数据源',
char_can_not_more_50: '名称不能超过50字符',
char_can_not_more_50: '不能超过50字符',
share_success: '分享成功'
},
documentation: {
@@ -435,7 +435,8 @@ export default {
current_user: '当前用户',
origin_passwd: '原始密码',
new_passwd: '新密码',
confirm_passwd: '确认密码'
confirm_passwd: '确认密码',
change_password: '修改密码'
},
role: {
menu_authorization: '菜单授权',
@@ -677,7 +678,8 @@ export default {
quota_show: '指标显示',
title_limit: '标题不能大于50个字符',
filter_condition: '过滤条件',
filter_field_can_null: '过滤字段必填'
filter_field_can_null: '过滤字段必填',
preview_100_data: '预览前100条记录'
},
dataset: {
sheet_warn: '有多个Sheet页默认抽取第一个',
@@ -732,13 +734,13 @@ export default {
error: '错误',
completed: '完成',
underway: '执行中',
task_update: '定时更新',
task_update: '更新设置',
update_type: '更新方式',
all_scope: '全量更新',
add_scope: '增量更新',
select_data_time: '选择日期时间',
execute_rate: '执行频率',
execute_once: '只执行一次',
execute_once: '立即执行',
cron_config: '表达式设定',
no_limit: '无限制',
set_end_time: '设定结束时间',

View File

@@ -47,7 +47,7 @@
<el-dropdown-item>{{ $t('commons.personal_info') }}</el-dropdown-item>
</router-link>
<router-link to="/person-pwd/index">
<el-dropdown-item>{{ $t('user.reset_password') }}</el-dropdown-item>
<el-dropdown-item>{{ $t('user.change_password') }}</el-dropdown-item>
</router-link>
<a href="/swagger-ui.html" target="_blank">
<el-dropdown-item>{{ $t('commons.help_documentation') }} </el-dropdown-item>

View File

@@ -36,6 +36,14 @@ export const filterAsyncRouter = (routers) => { // 遍历后台传来的路由
if (router.type === 1 && router.pid === 0 && router.component && router.component !== 'Layout') {
router = decorate(router)
}
if (router.isPlugin) {
const jsName = router.component
router.component = 'system/plugin/dynamic'
router.props = {
jsname: jsName,
menuid: router.id
}
}
if (router.component) {
if (router.component === 'Layout') { // Layout组件特殊处理
router.component = Layout
@@ -47,6 +55,7 @@ export const filterAsyncRouter = (routers) => { // 遍历后台传来的路由
if (router.children && router.children.length) {
router.children = filterAsyncRouter(router.children)
}
router.hasOwnProperty('id') && delete router.id
router.hasOwnProperty('type') && delete router.type
router.hasOwnProperty('pid') && delete router.pid

View File

@@ -5,9 +5,9 @@
/* theme color */
$--color-primary: #0a7be0;
$--color-success: #13ce66;
$--color-warning: #ffba00;
$--color-danger: #ff4949;
$--color-success: #67C23A;
$--color-warning: #E6A23C;
$--color-danger: #F56C6C;
// $--color-info: #1E1E1E;
$--button-font-weight: 400;

View File

@@ -73,8 +73,8 @@
</el-dropdown-menu>
</el-dropdown>
</span>
<span style="margin-left: 12px;" @click.stop >
<el-dropdown trigger="click" size="small" @command="clickMore">
<span style="margin-left: 12px;" @click.stop>
<el-dropdown trigger="click" size="small" @command="clickMore">
<span class="el-dropdown-link">
<el-button
icon="el-icon-more"
@@ -156,8 +156,8 @@
<span style="margin-left: 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">{{ data.name }}</span>
</span>
<span v-if="hasDataPermission('manage',data.privileges)">
<span style="margin-left: 12px;" @click.stop >
<el-dropdown trigger="click" size="small" @command="clickMore">
<span style="margin-left: 12px;" @click.stop>
<el-dropdown trigger="click" size="small" @command="clickMore">
<span class="el-dropdown-link">
<el-button
icon="el-icon-more"
@@ -204,7 +204,7 @@
<el-row style="width: 400px;">
<el-form ref="form" :model="table" label-width="80px" size="mini" class="form-item">
<el-form-item :label="$t('chart.view_name')">
<el-input v-model="table.name" size="mini" />
<el-input v-model="chartName" size="mini" />
</el-form-item>
</el-form>
</el-row>
@@ -274,7 +274,8 @@ export default {
},
selectTableFlag: false,
table: {},
tables: []
tables: [],
chartName: ''
}
},
computed: {
@@ -547,7 +548,7 @@ export default {
},
createChart() {
if (!this.table.name || this.table.name === '') {
if (!this.chartName || this.chartName === '') {
this.$message({
message: this.$t('chart.name_can_not_empty'),
type: 'error',
@@ -555,7 +556,7 @@ export default {
})
return
}
if (this.table.name.length > 50) {
if (this.chartName.length > 50) {
this.$message({
showClose: true,
message: this.$t('commons.char_can_not_more_50'),
@@ -564,8 +565,8 @@ export default {
return
}
const view = {}
view.name = this.table.name
view.title = this.table.name
view.name = this.chartName
view.title = this.chartName
view.sceneId = this.currGroup.id
view.tableId = this.table.id
view.type = 'bar'

View File

@@ -98,7 +98,7 @@
<el-radio-group
v-model="view.type"
style="width: 100%"
@change="save(true)"
@change="save(true,'chart')"
>
<div style="width: 100%;display: flex;display: -webkit-flex;justify-content: space-between;flex-direction: row;flex-wrap: wrap;">
<el-radio value="table-normal" label="table-normal"><svg-icon icon-class="table-normal" class="chart-icon" /></el-radio>
@@ -430,7 +430,7 @@ export default {
return true
})
},
save(getData) {
save(getData, trigger) {
const view = JSON.parse(JSON.stringify(this.view))
view.id = this.view.id
view.sceneId = this.view.sceneId
@@ -471,6 +471,12 @@ export default {
view.yaxis.splice(1, view.yaxis.length)
}
}
if (view.type === 'line' && trigger === 'chart') {
view.customAttr.size.lineArea = false
}
if (view.type === 'line-stack' && trigger === 'chart') {
view.customAttr.size.lineArea = true
}
view.xaxis = JSON.stringify(view.xaxis)
view.yaxis = JSON.stringify(view.yaxis)
view.customAttr = JSON.stringify(view.customAttr)

View File

@@ -51,7 +51,7 @@
</el-col>
<!--scene-->
<el-col v-if="sceneMode">
<el-col v-if="sceneMode" v-loading="dsLoading">
<el-row class="title-css">
<span class="title-text">
{{ currGroup.name }}
@@ -150,7 +150,8 @@ export default {
tableForm: {
name: '',
sort: 'type asc,create_time desc,name asc'
}
},
dsLoading: false
}
},
computed: {},
@@ -219,6 +220,7 @@ export default {
tableTree() {
this.tableData = []
if (this.currGroup) {
this.dsLoading = true
post('/dataset/table/list', {
sort: 'type asc,create_time desc,name asc',
sceneId: this.currGroup.id,
@@ -235,6 +237,9 @@ export default {
this.$nextTick(function() {
this.unionDataChange()
})
this.dsLoading = false
}).catch(res => {
this.dsLoading = false
})
}
},

View File

@@ -1,5 +1,5 @@
<template>
<el-col ref="container" style="width: 100%;height:100%">
<el-col ref="container" v-loading="dataLoading" style="width: 100%;height:100%">
<span>{{ table.name }}</span>
<ux-grid
ref="plxTable"
@@ -14,10 +14,17 @@
:key="field.dataeaseName"
min-width="200px"
:field="field.dataeaseName"
:title="field.name"
:resizable="true"
/>
>
<template slot="header">
<svg-icon v-if="field.deType === 0" icon-class="field_text" class="field-icon-text" />
<svg-icon v-if="field.deType === 1" icon-class="field_time" class="field-icon-time" />
<svg-icon v-if="field.deType === 2 || field.deType === 3" icon-class="field_value" class="field-icon-value" />
<span>{{ field.name }}</span>
</template>
</ux-table-column>
</ux-grid>
<span v-if="table.name" style="font-size: 12px;">{{ $t('chart.preview_100_data') }}</span>
</el-col>
</template>
@@ -36,7 +43,8 @@ export default {
return {
fields: [],
data: [],
height: 'auto'
height: 'auto',
dataLoading: false
}
},
watch: {
@@ -57,8 +65,9 @@ export default {
initData() {
this.resetData()
if (this.table.id) {
this.table.row = 10
post('/dataset/table/getPreviewData/1/10', this.table).then(response => {
this.dataLoading = true
this.table.row = 100
post('/dataset/table/getPreviewData/1/100', this.table).then(response => {
this.fields = response.data.fields
this.data = response.data.data
const datas = this.data
@@ -69,6 +78,9 @@ export default {
this.$error(response.data.msg, 3000)
}
this.$refs.plxTable.reloadData(datas)
this.dataLoading = false
}).catch(res => {
this.dataLoading = false
})
}
},

View File

@@ -169,7 +169,7 @@ export default {
font-size: 12px;
}
.span-number{
color: #f18126;
color: #0a7be0;
}
.table-count{
color: #606266;

View File

@@ -116,14 +116,6 @@
/>
</el-select>
</el-form-item>
<el-form-item :label="$t('dataset.start_time')" prop="startTime">
<el-date-picker
v-model="taskForm.startTime"
type="datetime"
:placeholder="$t('dataset.select_data_time')"
size="mini"
/>
</el-form-item>
<el-form-item :label="$t('dataset.execute_rate')" prop="rate">
<el-select v-model="taskForm.rate" size="mini" @change="onRateChange">
<el-option
@@ -136,13 +128,22 @@
/>
</el-select>
</el-form-item>
<el-form-item v-if="taskForm.rate === 'CRON'" label="">
<el-popover v-model="cronEdit">
<cron v-model="taskForm.cron" @close="cronEdit = false" />
<el-input slot="reference" v-model="taskForm.cron" size="mini" style="width: 50%" @click="cronEdit = true" />
</el-popover>
</el-form-item>
<el-form-item :label="$t('dataset.end_time')" prop="end">
<el-form-item v-if="taskForm.rate === 'CRON'" :label="$t('dataset.start_time')" prop="startTime">
<el-date-picker
v-model="taskForm.startTime"
type="datetime"
:placeholder="$t('dataset.select_data_time')"
size="mini"
/>
</el-form-item>
<el-form-item v-if="taskForm.rate === 'CRON'" :label="$t('dataset.end_time')" prop="end">
<el-select v-model="taskForm.end" size="mini">
<el-option
:label="$t('dataset.no_limit')"
@@ -498,6 +499,7 @@ export default {
this.update_task = false
this.resetTaskForm()
this.listTask()
this.listTaskLog()
})
},
deleteTask(task) {
@@ -514,6 +516,7 @@ export default {
})
this.resetTaskForm()
this.listTask()
this.listTaskLog()
})
}).catch(() => {
})

View File

@@ -94,8 +94,10 @@ export default {
this.$refs.dsForm.validate(valid => {
if (valid) {
const method = this.formType === 'add' ? addDs : editDs
this.form.configuration = JSON.stringify(this.form.configuration)
method(this.form).then(res => {
// this.form.configuration = JSON.stringify(this.form.configuration)
const form = JSON.parse(JSON.stringify(this.form))
form.configuration = JSON.stringify(form.configuration)
method(form).then(res => {
this.$success(this.$t('commons.save_success'))
this.backToList()
})

View File

@@ -0,0 +1,84 @@
<template>
<layout-content v-loading="$store.getters.loadingMap[$store.getters.currentPath]" :header="header" :back-name="backName">
<async-component v-if="showAsync" :url="url" @execute-axios="executeAxios" @on-add-languanges="addLanguages" @on-plugin-layout="setLayoutInfo" />
<div v-else>
<h1>未知组件无法展示</h1>
</div>
</layout-content>
</template>
<script>
import LayoutContent from '@/components/business/LayoutContent'
import AsyncComponent from '@/components/AsyncComponent'
import i18n from '@/lang'
import { execute } from '@/api/system/dynamic'
export default {
name: 'Dynamic',
components: {
LayoutContent,
AsyncComponent
},
props: {
jsname: {
type: String,
default: null
},
menuid: {
type: Number,
default: null
}
},
data() {
return {
showAsync: false,
header: null,
backName: null,
baseUrl: '/api/pluginCommon/async/',
url: null
}
},
created() {
if (this.jsname && this.menuid) {
this.showAsync = true
console.log(this.jsname)
this.url = this.baseUrl + this.menuid
// this.url = 'http://localhost:8081/PluginDemo.js'
// this.url = 'http://localhost:8081/SystemParam.js'
} else {
this.showAsync = false
}
},
methods: {
// hasLicense
executeAxios(options) {
execute(options).then(res => {
if (options.callBack) {
options.callBack(res)
}
}).catch(e => {
if (options.callBack) {
options.callBack(e)
}
})
},
addLanguages(options) {
for (const key in i18n.messages) {
if (Object.hasOwnProperty.call(i18n.messages, key)) {
const element = options[key]
i18n.mergeLocaleMessage(key, element)
}
}
},
setLayoutInfo(param) {
const { header, backName } = param
this.header = header
this.backName = backName
}
}
}
</script>
<style scoped>
</style>

View File

@@ -54,7 +54,7 @@ import ComplexTable from '@/components/business/complex-table'
import { checkPermission } from '@/utils/permission'
import { formatCondition } from '@/utils/index'
import { pluginLists } from '@/api/system/plugin'
import { pluginLists, uninstall } from '@/api/system/plugin'
import { getToken } from '@/utils/auth'
export default {
@@ -131,6 +131,12 @@ export default {
cancelButtonText: this.$t('commons.cancel'),
type: 'warning'
}).then(() => {
uninstall(row.pluginId).then(res => {
this.search()
this.$success('卸载成功')
}).catch(() => {
this.$error('卸载失败')
})
}).catch(() => {
this.$info(this.$t('commons.delete_cancel'))
})

View File

@@ -30,7 +30,7 @@ export default {
name: [
{ required: true, trigger: 'blur', validator: this.roleValidator }
],
code: [{ required: true, message: '请输入代码', trigger: 'blur' }]
description: [{ max: 50, message: this.$t('commons.char_can_not_more_50'), trigger: 'blur' }]
},
roles: [],
originName: null

View File

@@ -18,6 +18,7 @@
</template>
<el-table-column prop="name" :label="$t('commons.name')" />
<el-table-column :show-overflow-tooltip="true" prop="description" :label="$t('commons.description')" />
<el-table-column :show-overflow-tooltip="true" prop="createTime" :label="$t('commons.create_time')">
<template v-slot:default="scope">
<span>{{ scope.row.createTime | timestampFormatDate }}</span>
@@ -118,9 +119,9 @@ export default {
columns: [],
buttons: [
{
label: this.$t('commons.edit'), icon: 'el-icon-edit', type: 'primary', click: this.edit
label: this.$t('commons.edit'), icon: 'el-icon-edit', type: 'primary', click: this.edit, disabled: this.btnDisabled
}, {
label: this.$t('commons.delete'), icon: 'el-icon-delete', type: 'danger', click: this.handleDelete
label: this.$t('commons.delete'), icon: 'el-icon-delete', type: 'danger', click: this.handleDelete, disabled: this.btnDisabled
}
],
searchConfig: {
@@ -156,7 +157,7 @@ export default {
const param = temp || {}
roleGrid(this.paginationConfig.currentPage, this.paginationConfig.pageSize, param).then(response => {
const data = response.data
this.total = data.itemCount
this.paginationConfig.total = data.itemCount
this.tableData = data.listObject
})
},
@@ -251,18 +252,21 @@ export default {
this.$refs.menu.setCheckedKeys(this.menuIds)
},
handleDelete(row) {
this.$confirm(this.$t('commons.confirm_delete') + ': ' + row.name + '', this.$t('role.tips'), {
this.$confirm(this.$t('role.confirm_delete') + ': ' + row.name + '', this.$t('role.tips'), {
confirmButtonText: this.$t('commons.confirm'),
cancelButtonText: this.$t('commons.cancel'),
type: 'warning'
}).then(() => {
delRole(row.roleId).then(res => {
this.$success(this.$t('commons.modify_success'))
this.$success(this.$t('commons.delete_success'))
this.search()
})
}).catch(() => {
})
},
btnDisabled(row) {
return !row.updateTime
}
}
}

View File

@@ -25,6 +25,24 @@
<div>{{ scope.row.dept && scope.row.dept.deptName }}</div>
</template>
</el-table-column>
<el-table-column prop="roles" :label="$t('commons.role')">
<template slot-scope="scope">
<div v-if="scope.row.roles && scope.row.roles.length <= 2">
<div v-for="role in scope.row.roles" :key="role.roleId">{{ role.roleName }}</div>
</div>
<div v-if="scope.row.roles && scope.row.roles.length > 2">
<el-tooltip placement="top">
<div slot="content">
<div v-for="role in scope.row.roles" :key="role.roleId">{{ role.roleName }}</div>
</div>
<div>
<div v-for="(role,index) in scope.row.roles" v-if="index < 2" :key="role.roleId">{{ role.roleName }}</div>
<div>...</div>
</div>
</el-tooltip>
</div>
</template>
</el-table-column>
<el-table-column prop="status" :label="$t('commons.status')">
<template v-slot:default="scope">
<el-switch v-model="scope.row.enabled" :active-value="1" :inactive-value="0" inactive-color="#DCDFE6" @change="changeSwitch(scope.row)" />

View File

@@ -1,5 +1,5 @@
<template>
<layout-content :header="$t('member.edit_password')">
<layout-content :header="$t('user.change_password')">
<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">