Merge branch 'main' of github.com:dataease/dataease into main

This commit is contained in:
taojinlong 2021-04-29 10:47:25 +08:00
commit bde937f97a
37 changed files with 860 additions and 296 deletions

View File

@ -25,6 +25,8 @@ public class DynamicMenuDto implements Serializable {
private String permission; private String permission;
private Boolean hidden;
private List<DynamicMenuDto> children; private List<DynamicMenuDto> children;
} }

View File

@ -68,6 +68,9 @@ public class F2CRealm extends AuthorizingRealm {
if (user == null) { if (user == null) {
throw new AuthenticationException("User didn't existed!"); throw new AuthenticationException("User didn't existed!");
} }
if (user.getEnabled()==0) {
throw new AuthenticationException("User is valid!");
}
String pass = null; String pass = null;
try { try {
pass = user.getPassword(); pass = user.getPassword();

View File

@ -35,10 +35,14 @@ public class AuthServer implements AuthApi {
String username = loginDto.getUsername(); String username = loginDto.getUsername();
String password = loginDto.getPassword(); String password = loginDto.getPassword();
SysUserEntity user = authUserService.getUserByName(username); SysUserEntity user = authUserService.getUserByName(username);
String realPwd = user.getPassword();
if (ObjectUtils.isEmpty(user)){ if (ObjectUtils.isEmpty(user)){
throw new RuntimeException("没有该用户!"); throw new RuntimeException("没有该用户!");
} }
if (user.getEnabled()==0){
throw new RuntimeException("用户已经失效!");
}
String realPwd = user.getPassword();
//私钥解密 //私钥解密
String pwd = RsaUtil.decryptByPrivateKey(RsaProperties.privateKey, password); String pwd = RsaUtil.decryptByPrivateKey(RsaProperties.privateKey, password);
//md5加密 //md5加密

View File

@ -42,6 +42,7 @@ public class DynamicMenuServiceImpl implements DynamicMenuService {
menuMeta.setIcon(sysMenu.getIcon()); menuMeta.setIcon(sysMenu.getIcon());
dynamicMenuDto.setMeta(menuMeta); dynamicMenuDto.setMeta(menuMeta);
dynamicMenuDto.setPermission(sysMenu.getPermission()); dynamicMenuDto.setPermission(sysMenu.getPermission());
dynamicMenuDto.setHidden(sysMenu.getHidden());
return dynamicMenuDto; return dynamicMenuDto;
} }

View File

@ -13,6 +13,8 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationException;
import org.springframework.cache.Cache; import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager; import org.springframework.cache.CacheManager;
import org.springframework.core.env.Environment;
import java.util.Date; import java.util.Date;
@ -22,7 +24,9 @@ public class JWTUtils {
// token过期时间1min (过期会自动刷新续命 目的是避免一直都是同一个token ) // token过期时间1min (过期会自动刷新续命 目的是避免一直都是同一个token )
private static final long EXPIRE_TIME = 1*60*1000; private static final long EXPIRE_TIME = 1*60*1000;
// 登录间隔时间10min 超过这个时间强制重新登录 // 登录间隔时间10min 超过这个时间强制重新登录
private static final long Login_Interval = 10*60*1000; private static long Login_Interval;
/** /**
@ -79,6 +83,11 @@ public class JWTUtils {
* @return * @return
*/ */
public static boolean loginExpire(String token){ public static boolean loginExpire(String token){
if (Login_Interval==0) {
String property = CommonBeanFactory.getBean(Environment.class).getProperty("dataease.login_timeout");
int seconds = StringUtils.isNotEmpty(property) ? Integer.parseInt(property): (10*60);
Login_Interval = seconds * 1000;
}
Long now = System.currentTimeMillis(); Long now = System.currentTimeMillis();
Long lastOperateTime = tokenLastOperateTime(token); Long lastOperateTime = tokenLastOperateTime(token);
boolean isExpire = false; boolean isExpire = false;
@ -169,4 +178,5 @@ public class JWTUtils {
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
tokens_expire.put(token, now); tokens_expire.put(token, now);
} }
} }

View File

@ -63,9 +63,9 @@ public class DataSetTableController {
return dataSetTableService.getData(dataSetTableRequest); return dataSetTableService.getData(dataSetTableRequest);
} }
@PostMapping("getPreviewData") @PostMapping("getPreviewData/{page}/{pageSize}")
public Map<String, Object> getPreviewData(@RequestBody DataSetTableRequest dataSetTableRequest) throws Exception { public Map<String, Object> getPreviewData(@RequestBody DataSetTableRequest dataSetTableRequest, @PathVariable Integer page, @PathVariable Integer pageSize) throws Exception {
return dataSetTableService.getPreviewData(dataSetTableRequest); return dataSetTableService.getPreviewData(dataSetTableRequest, page, pageSize);
} }
@PostMapping("sqlPreview") @PostMapping("sqlPreview")

View File

@ -0,0 +1,17 @@
package io.dataease.dto.dataset;
import lombok.Getter;
import lombok.Setter;
/**
* @Author gin
* @Date 2021/4/28 11:13 上午
*/
@Getter
@Setter
public class DataSetPreviewPage {
private Integer total = 0;
private Integer show = 0;
private Integer page = 1;
private Integer pageSize = 100;
}

View File

@ -14,6 +14,7 @@ import io.dataease.datasource.dto.TableFiled;
import io.dataease.datasource.provider.DatasourceProvider; import io.dataease.datasource.provider.DatasourceProvider;
import io.dataease.datasource.provider.ProviderFactory; import io.dataease.datasource.provider.ProviderFactory;
import io.dataease.datasource.request.DatasourceRequest; import io.dataease.datasource.request.DatasourceRequest;
import io.dataease.dto.dataset.DataSetPreviewPage;
import io.dataease.dto.dataset.DataTableInfoDTO; import io.dataease.dto.dataset.DataTableInfoDTO;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.ObjectUtils;
@ -34,7 +35,6 @@ import javax.annotation.Resource;
import java.io.*; import java.io.*;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.sql.ResultSet;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -172,7 +172,7 @@ public class DataSetTableService {
return datasourceProvider.getData(datasourceRequest); return datasourceProvider.getData(datasourceRequest);
} }
public Map<String, Object> getPreviewData(DataSetTableRequest dataSetTableRequest) throws Exception { public Map<String, Object> getPreviewData(DataSetTableRequest dataSetTableRequest, Integer page, Integer pageSize) throws Exception {
DatasetTableField datasetTableField = DatasetTableField.builder().build(); DatasetTableField datasetTableField = DatasetTableField.builder().build();
datasetTableField.setTableId(dataSetTableRequest.getId()); datasetTableField.setTableId(dataSetTableRequest.getId());
datasetTableField.setChecked(Boolean.TRUE); datasetTableField.setChecked(Boolean.TRUE);
@ -183,6 +183,14 @@ public class DataSetTableService {
DatasetTable datasetTable = datasetTableMapper.selectByPrimaryKey(dataSetTableRequest.getId()); DatasetTable datasetTable = datasetTableMapper.selectByPrimaryKey(dataSetTableRequest.getId());
List<String[]> data = new ArrayList<>(); List<String[]> data = new ArrayList<>();
DataSetPreviewPage dataSetPreviewPage = new DataSetPreviewPage();
dataSetPreviewPage.setShow(Integer.valueOf(dataSetTableRequest.getRow()));
dataSetPreviewPage.setPage(page);
dataSetPreviewPage.setPageSize(pageSize);
int realSize = Integer.parseInt(dataSetTableRequest.getRow()) < pageSize ? Integer.parseInt(dataSetTableRequest.getRow()) : pageSize;
if (page == Integer.parseInt(dataSetTableRequest.getRow()) / pageSize + 1) {
realSize = Integer.parseInt(dataSetTableRequest.getRow()) % pageSize;
}
if (StringUtils.equalsIgnoreCase(datasetTable.getType(), "db")) { if (StringUtils.equalsIgnoreCase(datasetTable.getType(), "db")) {
Datasource ds = datasourceMapper.selectByPrimaryKey(dataSetTableRequest.getDataSourceId()); Datasource ds = datasourceMapper.selectByPrimaryKey(dataSetTableRequest.getDataSourceId());
DatasourceProvider datasourceProvider = ProviderFactory.getProvider(ds.getType()); DatasourceProvider datasourceProvider = ProviderFactory.getProvider(ds.getType());
@ -190,11 +198,18 @@ public class DataSetTableService {
datasourceRequest.setDatasource(ds); datasourceRequest.setDatasource(ds);
String table = dataTableInfoDTO.getTable(); String table = dataTableInfoDTO.getTable();
datasourceRequest.setQuery(createQuerySQL(ds.getType(), table, fieldArray) + " LIMIT 0," + dataSetTableRequest.getRow()); datasourceRequest.setQuery(createQuerySQL(ds.getType(), table, fieldArray) + " LIMIT " + (page - 1) * realSize + "," + realSize);
try { try {
data.addAll(datasourceProvider.getData(datasourceRequest)); data.addAll(datasourceProvider.getData(datasourceRequest));
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace();
}
try {
datasourceRequest.setQuery(createQueryCountSQL(ds.getType(), table));
dataSetPreviewPage.setTotal(Integer.valueOf(datasourceProvider.getData(datasourceRequest).get(0)[0]));
} catch (Exception e) {
e.printStackTrace();
} }
} else if (StringUtils.equalsIgnoreCase(datasetTable.getType(), "sql")) { } else if (StringUtils.equalsIgnoreCase(datasetTable.getType(), "sql")) {
Datasource ds = datasourceMapper.selectByPrimaryKey(dataSetTableRequest.getDataSourceId()); Datasource ds = datasourceMapper.selectByPrimaryKey(dataSetTableRequest.getDataSourceId());
@ -203,11 +218,18 @@ public class DataSetTableService {
datasourceRequest.setDatasource(ds); datasourceRequest.setDatasource(ds);
String sql = dataTableInfoDTO.getSql(); String sql = dataTableInfoDTO.getSql();
datasourceRequest.setQuery(createQuerySQL(ds.getType(), " (" + sql + ") AS tmp ", fieldArray) + " LIMIT 0," + dataSetTableRequest.getRow()); datasourceRequest.setQuery(createQuerySQL(ds.getType(), " (" + sql + ") AS tmp ", fieldArray) + " LIMIT " + (page - 1) * realSize + "," + realSize);
try { try {
data.addAll(datasourceProvider.getData(datasourceRequest)); data.addAll(datasourceProvider.getData(datasourceRequest));
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace();
}
try {
datasourceRequest.setQuery(createQueryCountSQL(ds.getType(), " (" + sql + ") AS tmp "));
dataSetPreviewPage.setTotal(Integer.valueOf(datasourceProvider.getData(datasourceRequest).get(0)[0]));
} catch (Exception e) {
e.printStackTrace();
} }
} else if (StringUtils.equalsIgnoreCase(datasetTable.getType(), "excel")) { } else if (StringUtils.equalsIgnoreCase(datasetTable.getType(), "excel")) {
@ -229,6 +251,7 @@ public class DataSetTableService {
Map<String, Object> map = new HashMap<>(); Map<String, Object> map = new HashMap<>();
map.put("fields", fields); map.put("fields", fields);
map.put("data", jsonArray); map.put("data", jsonArray);
map.put("page", dataSetPreviewPage);
return map; return map;
} }
@ -314,6 +337,18 @@ public class DataSetTableService {
} }
} }
public String createQueryCountSQL(String type, String table) {
DatasourceTypes datasourceType = DatasourceTypes.valueOf(type);
switch (datasourceType) {
case mysql:
return MessageFormat.format("SELECT count(*) FROM {0}", table);
case sqlServer:
return MessageFormat.format("SELECT count(*) FROM {0}", table);
default:
return MessageFormat.format("SELECT count(*) FROM {0}", table);
}
}
public String createQuerySQL(String type, String table, String[] fields) { public String createQuerySQL(String type, String table, String[] fields) {
DatasourceTypes datasourceType = DatasourceTypes.valueOf(type); DatasourceTypes datasourceType = DatasourceTypes.valueOf(type);
switch (datasourceType) { switch (datasourceType) {

View File

@ -15,12 +15,12 @@ import io.dataease.controller.sys.base.BaseGridRequest;
import io.dataease.controller.sys.request.SysUserCreateRequest; import io.dataease.controller.sys.request.SysUserCreateRequest;
import io.dataease.controller.sys.request.SysUserPwdRequest; import io.dataease.controller.sys.request.SysUserPwdRequest;
import io.dataease.controller.sys.request.SysUserStateRequest; import io.dataease.controller.sys.request.SysUserStateRequest;
import io.dataease.controller.sys.request.UserGridRequest;
import io.dataease.controller.sys.response.SysUserGridResponse; import io.dataease.controller.sys.response.SysUserGridResponse;
import io.dataease.controller.sys.response.SysUserRole; import io.dataease.controller.sys.response.SysUserRole;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -31,7 +31,10 @@ import java.util.stream.Collectors;
@Service @Service
public class SysUserService { public class SysUserService {
private final static String DEFAULT_PWD = "DataEase123.."; //private final static String DEFAULT_PWD = "DataEase123..";
@Value("${dataease.init_password:DataEase123..}")
private String DEFAULT_PWD;
@Resource @Resource
private SysUserMapper sysUserMapper; private SysUserMapper sysUserMapper;
@ -89,6 +92,7 @@ public class SysUserService {
} }
@CacheEvict(value = AuthConstants.USER_CACHE_NAME, key = "'user' + #request.userId")
public int updateStatus(SysUserStateRequest request){ public int updateStatus(SysUserStateRequest request){
SysUser sysUser = new SysUser(); SysUser sysUser = new SysUser();
sysUser.setUserId(request.getUserId()); sysUser.setUserId(request.getUserId());

View File

@ -62,6 +62,10 @@ spring.mvc.log-request-details=true
pagehelper.PageRowBounds=true pagehelper.PageRowBounds=true
#excel等用户上传文件路径 #excel等用户上传文件路径
upload.file.path=/opt/dataease/data/upload/ upload.file.path=/opt/dataease/data/upload/
#用户初始密码,如果不设置默认是DataEase123..
dataease.init_password=DataEase123456
#登录超时时间单位s 设置默认30分钟 如果雨不设置 默认10分钟也就是10*60
dataease.login_timeout=1800

View File

@ -22,7 +22,7 @@
"element-resize-detector": "^1.2.2", "element-resize-detector": "^1.2.2",
"element-ui": "2.13.0", "element-ui": "2.13.0",
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
"fit2cloud-ui": "^0.1.12", "fit2cloud-ui": "^1.1.1",
"html2canvas": "^1.0.0-rc.7", "html2canvas": "^1.0.0-rc.7",
"js-cookie": "2.2.0", "js-cookie": "2.2.0",
"jsencrypt": "^3.0.0-rc.1", "jsencrypt": "^3.0.0-rc.1",

View File

@ -0,0 +1,46 @@
<template>
<el-icon name="back" class="back-button" @click.native="jump" />
</template>
<script>
export default {
name: 'BackButton',
props: {
// eslint-disable-next-line vue/require-default-prop
path: String,
// eslint-disable-next-line vue/require-default-prop
name: String,
// eslint-disable-next-line vue/require-default-prop
to: Object
},
methods: {
jump() {
const { path, name, to } = this
if (path) {
this.$router.push(path)
}
if (name) {
this.$router.push({ name: this.name })
}
if (to) {
this.$router.push(to)
}
}
}
}
</script>
<style lang="scss">
@import "~@/styles/mixin.scss";
@import "~@/styles/variables.scss";
.back-button {
cursor: pointer;
margin-right: 10px;
font-weight: 600;
&:active {
transform: scale(0.85);
}
}
</style>

View File

@ -1,17 +1,45 @@
<template> <template>
<div class="content-container"> <div class="content-container">
<div v-if="$slots.header || header" class="content-container__header">
<slot name="header">
<back-button v-if="showBack" :path="backPath" :name="backName" :to="backTo" />
{{ header }}
</slot>
</div>
<div v-if="$slots.toolbar" class="content-container__toolbar">
<slot name="toolbar" />
</div>
<slot /> <slot />
</div> </div>
</template> </template>
<script> <script>
import BackButton from '@/components/back-button'
export default { export default {
name: 'LayoutContent' name: 'LayoutContent',
components: { BackButton },
props: {
// eslint-disable-next-line vue/require-default-prop
header: String,
// eslint-disable-next-line vue/require-default-prop
backPath: String,
// eslint-disable-next-line vue/require-default-prop
backName: String,
// eslint-disable-next-line vue/require-default-prop
backTo: Object
},
computed: {
showBack({ backPath, backName, backTo }) {
return backPath || backName || backTo
}
}
} }
</script> </script>
<style lang="scss"> <style lang="scss">
@import "~@/styles/variables"; @import "~@/styles/mixin.scss";
@import "~@/styles/variables.scss";
.content-container { .content-container {
transition: 0.3s; transition: 0.3s;
@ -23,5 +51,15 @@ export default {
border-radius: 4px; border-radius: 4px;
box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 14%); box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 14%);
box-sizing: border-box; box-sizing: border-box;
.content-container__header {
line-height: 60px;
font-size: 18px;
}
.content-container__toolbar {
@include flex-row(space-between, center);
margin-bottom: 10px;
}
} }
</style> </style>

View File

@ -1,3 +1,4 @@
<template> <template>
<div class="complex-table"> <div class="complex-table">
<div v-if="$slots.header || header" class="complex-table__header"> <div v-if="$slots.header || header" class="complex-table__header">
@ -5,12 +6,16 @@
</div> </div>
<div v-if="$slots.toolbar || searchConfig" class="complex-table__toolbar"> <div v-if="$slots.toolbar || searchConfig" class="complex-table__toolbar">
<slot name="toolbar"> <div>
<slot name="toolbar" />
</div>
<fu-search-bar v-bind="searchConfig" @exec="search"> <fu-search-bar v-bind="searchConfig" @exec="search">
<template #complex>
<slot name="complex" />
</template>
<slot name="buttons" /> <slot name="buttons" />
<fu-table-column-select :columns="columns" /> <fu-table-column-select :columns="columns" />
</fu-search-bar> </fu-search-bar>
</slot>
</div> </div>
<div class="complex-table__body"> <div class="complex-table__body">
@ -41,13 +46,9 @@ export default {
type: Array, type: Array,
default: () => [] default: () => []
}, },
// eslint-disable-next-line vue/require-default-prop
localKey: String, // Key localKey: String, // Key
// eslint-disable-next-line vue/require-default-prop
header: String, header: String,
// eslint-disable-next-line vue/require-default-prop
searchConfig: Object, searchConfig: Object,
// eslint-disable-next-line vue/require-default-prop
paginationConfig: Object paginationConfig: Object
}, },
data() { data() {
@ -72,12 +73,16 @@ export default {
.complex-table { .complex-table {
.complex-table__header { .complex-table__header {
@include flex-row(flex-start, center); @include flex-row(flex-start, center);
height: 60px; line-height: 60px;
font-size: 20px; font-size: 18px;
} }
.complex-table__toolbar { .complex-table__toolbar {
@include flex-row(flex-end, center); @include flex-row(space-between, center);
.fu-search-bar {
width: auto;
}
} }
.complex-table__pagination { .complex-table__pagination {

View File

@ -5,12 +5,22 @@
</div> </div>
<div v-if="$slots.toolbar || searchConfig" class="complex-table__toolbar"> <div v-if="$slots.toolbar || searchConfig" class="complex-table__toolbar">
<slot name="toolbar"> <!-- <slot name="toolbar">
<fu-search-bar v-bind="searchConfig" @exec="search"> <fu-search-bar v-bind="searchConfig" @exec="search">
<slot name="buttons" /> <slot name="buttons" />
<fu-table-column-select :columns="columns" /> <fu-table-column-select :columns="columns" />
</fu-search-bar> </fu-search-bar>
</slot> </slot> -->
<div>
<slot name="toolbar" />
</div>
<fu-search-bar v-bind="searchConfig" @exec="search">
<template #complex>
<slot name="complex" />
</template>
<slot name="buttons" />
<fu-table-column-select :columns="columns" />
</fu-search-bar>
</div> </div>
<div class="complex-table__body"> <div class="complex-table__body">
@ -73,12 +83,16 @@ export default {
.complex-table { .complex-table {
.complex-table__header { .complex-table__header {
@include flex-row(flex-start, center); @include flex-row(flex-start, center);
height: 60px; line-height: 60px;
font-size: 20px; font-size: 18px;
} }
.complex-table__toolbar { .complex-table__toolbar {
@include flex-row(flex-end, center); @include flex-row(space-between, center);
.fu-search-bar {
width: auto;
}
} }
.complex-table__pagination { .complex-table__pagination {

View File

@ -791,7 +791,11 @@ export default {
type: '类型', type: '类型',
create_by: '创建者', create_by: '创建者',
create_time: '创建时间', create_time: '创建时间',
preview_100_data: '预览前100行数据' preview_100_data: '预览前100行数据',
preview_show: '显示',
preview_item: '条数据',
preview_total: '共',
pls_input_less_9: '请输入9位以内的正整数'
}, },
datasource: { datasource: {
datasource: '数据源', datasource: '数据源',

View File

@ -2,9 +2,9 @@
<section class="app-main"> <section class="app-main">
<transition name="fade-transform" mode="out-in"> <transition name="fade-transform" mode="out-in">
<el-main class="ms-main-container"> <el-main class="ms-main-container">
<keep-alive> <!-- <keep-alive> -->
<router-view :key="key" /> <router-view :key="key" />
</keep-alive> <!-- </keep-alive> -->
</el-main> </el-main>
</transition> </transition>
</section> </section>

View File

@ -7,3 +7,10 @@
align-items: $align; align-items: $align;
} }
} }
@mixin variant($color, $background-color, $border-color) {
color: $color;
background-color: $background-color;
border-color: $border-color;
}

View File

@ -37,3 +37,9 @@
} }
} }
@mixin variant($color, $background-color, $border-color) {
color: $color;
background-color: $background-color;
border-color: $border-color;
}

View File

@ -88,6 +88,9 @@ export const BASE_BAR = {
title: { title: {
text: '' text: ''
}, },
grid: {
containLabel: true
},
tooltip: {}, tooltip: {},
legend: { legend: {
show: true, show: true,
@ -114,6 +117,9 @@ export const HORIZONTAL_BAR = {
title: { title: {
text: '' text: ''
}, },
grid: {
containLabel: true
},
tooltip: {}, tooltip: {},
legend: { legend: {
show: true, show: true,
@ -141,6 +147,9 @@ export const BASE_LINE = {
title: { title: {
text: '' text: ''
}, },
grid: {
containLabel: true
},
tooltip: {}, tooltip: {},
legend: { legend: {
show: true, show: true,
@ -169,6 +178,9 @@ export const BASE_PIE = {
title: { title: {
text: '' text: ''
}, },
grid: {
containLabel: true
},
tooltip: {}, tooltip: {},
legend: { legend: {
show: true, show: true,
@ -199,6 +211,9 @@ export const BASE_FUNNEL = {
title: { title: {
text: '' text: ''
}, },
grid: {
containLabel: true
},
tooltip: { tooltip: {
trigger: 'item' trigger: 'item'
}, },
@ -252,6 +267,9 @@ export const BASE_RADAR = {
title: { title: {
text: '' text: ''
}, },
grid: {
containLabel: true
},
tooltip: {}, tooltip: {},
legend: { legend: {
show: true, show: true,

View File

@ -26,7 +26,7 @@
<el-radio-button label="right">{{ $t('chart.text_pos_right') }}</el-radio-button> <el-radio-button label="right">{{ $t('chart.text_pos_right') }}</el-radio-button>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item v-if="chart.type && !chart.type.includes('table')" :label="$t('chart.text_v_position')" class="form-item"> <el-form-item v-show="chart.type && !chart.type.includes('table')" :label="$t('chart.text_v_position')" class="form-item">
<el-radio-group v-model="titleForm.vPosition" size="mini" @change="changeTitleStyle"> <el-radio-group v-model="titleForm.vPosition" size="mini" @change="changeTitleStyle">
<el-radio-button label="top">{{ $t('chart.text_pos_top') }}</el-radio-button> <el-radio-button label="top">{{ $t('chart.text_pos_top') }}</el-radio-button>
<el-radio-button label="center">{{ $t('chart.text_pos_center') }}</el-radio-button> <el-radio-button label="center">{{ $t('chart.text_pos_center') }}</el-radio-button>

View File

@ -8,7 +8,7 @@
> >
<el-col> <el-col>
<el-form ref="colorForm" :model="colorForm" label-width="80px" size="mini"> <el-form ref="colorForm" :model="colorForm" label-width="80px" size="mini">
<el-form-item v-if="chart.type && !chart.type.includes('table')" :label="$t('chart.color_case')" class="form-item"> <el-form-item v-show="chart.type && !chart.type.includes('table')" :label="$t('chart.color_case')" class="form-item">
<el-select v-model="colorForm.value" :placeholder="$t('chart.pls_slc_color_case')" size="mini" @change="changeColorCase"> <el-select v-model="colorForm.value" :placeholder="$t('chart.pls_slc_color_case')" size="mini" @change="changeColorCase">
<el-option v-for="option in colorCases" :key="option.value" :label="option.name" :value="option.value" style="display: flex;align-items: center;"> <el-option v-for="option in colorCases" :key="option.value" :label="option.name" :value="option.value" style="display: flex;align-items: center;">
<div style="float: left"> <div style="float: left">
@ -19,16 +19,16 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item v-if="chart.type && chart.type.includes('table')" :label="$t('chart.table_header_bg')" class="form-item"> <el-form-item v-show="chart.type && chart.type.includes('table')" :label="$t('chart.table_header_bg')" class="form-item">
<colorPicker v-model="colorForm.tableHeaderBgColor" style="margin-top: 6px;cursor: pointer;z-index: 1004;border: solid 1px black" @change="changeColorCase" /> <colorPicker v-model="colorForm.tableHeaderBgColor" style="margin-top: 6px;cursor: pointer;z-index: 1004;border: solid 1px black" @change="changeColorCase" />
</el-form-item> </el-form-item>
<el-form-item v-if="chart.type && chart.type.includes('table')" :label="$t('chart.table_item_bg')" class="form-item"> <el-form-item v-show="chart.type && chart.type.includes('table')" :label="$t('chart.table_item_bg')" class="form-item">
<colorPicker v-model="colorForm.tableItemBgColor" style="margin-top: 6px;cursor: pointer;z-index: 1003;border: solid 1px black" @change="changeColorCase" /> <colorPicker v-model="colorForm.tableItemBgColor" style="margin-top: 6px;cursor: pointer;z-index: 1003;border: solid 1px black" @change="changeColorCase" />
</el-form-item> </el-form-item>
<el-form-item v-if="chart.type && chart.type.includes('table')" :label="$t('chart.table_item_font_color')" class="form-item"> <el-form-item v-show="chart.type && chart.type.includes('table')" :label="$t('chart.table_item_font_color')" class="form-item">
<colorPicker v-model="colorForm.tableFontColor" style="margin-top: 6px;cursor: pointer;z-index: 1002;border: solid 1px black" @change="changeColorCase" /> <colorPicker v-model="colorForm.tableFontColor" style="margin-top: 6px;cursor: pointer;z-index: 1002;border: solid 1px black" @change="changeColorCase" />
</el-form-item> </el-form-item>
<el-form-item v-if="chart.type && chart.type.includes('table')" :label="$t('chart.stripe')" class="form-item"> <el-form-item v-show="chart.type && chart.type.includes('table')" :label="$t('chart.stripe')" class="form-item">
<el-checkbox v-model="colorForm.tableStripe" @change="changeColorCase">{{ $t('chart.stripe') }}</el-checkbox> <el-checkbox v-model="colorForm.tableStripe" @change="changeColorCase">{{ $t('chart.stripe') }}</el-checkbox>
</el-form-item> </el-form-item>

View File

@ -7,7 +7,7 @@
trigger="click" trigger="click"
> >
<el-col> <el-col>
<el-form v-if="chart.type && chart.type.includes('bar')" ref="sizeFormBar" :model="sizeForm" label-width="80px" size="mini"> <el-form v-show="chart.type && chart.type.includes('bar')" ref="sizeFormBar" :model="sizeForm" label-width="80px" size="mini">
<el-form-item :label="$t('chart.adapt')" class="form-item"> <el-form-item :label="$t('chart.adapt')" class="form-item">
<el-checkbox v-model="sizeForm.barDefault" @change="changeBarSizeCase">{{ $t('chart.adapt') }}</el-checkbox> <el-checkbox v-model="sizeForm.barDefault" @change="changeBarSizeCase">{{ $t('chart.adapt') }}</el-checkbox>
</el-form-item> </el-form-item>
@ -19,7 +19,7 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
<el-form v-if="chart.type && chart.type.includes('line')" ref="sizeFormLine" :model="sizeForm" label-width="80px" size="mini"> <el-form v-show="chart.type && chart.type.includes('line')" ref="sizeFormLine" :model="sizeForm" label-width="80px" size="mini">
<el-form-item :label="$t('chart.line_width')" class="form-item form-item-slider"> <el-form-item :label="$t('chart.line_width')" class="form-item form-item-slider">
<el-slider v-model="sizeForm.lineWidth" show-input :show-input-controls="false" input-size="mini" :min="0" :max="10" @change="changeBarSizeCase" /> <el-slider v-model="sizeForm.lineWidth" show-input :show-input-controls="false" input-size="mini" :min="0" :max="10" @change="changeBarSizeCase" />
</el-form-item> </el-form-item>
@ -50,7 +50,7 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
<el-form v-if="chart.type && chart.type.includes('pie')" ref="sizeFormPie" :model="sizeForm" label-width="80px" size="mini"> <el-form v-show="chart.type && chart.type.includes('pie')" ref="sizeFormPie" :model="sizeForm" label-width="80px" size="mini">
<el-form-item :label="$t('chart.pie_inner_radius')" class="form-item form-item-slider"> <el-form-item :label="$t('chart.pie_inner_radius')" class="form-item form-item-slider">
<el-slider v-model="sizeForm.pieInnerRadius" show-input :show-input-controls="false" input-size="mini" :min="0" :max="100" @change="changeBarSizeCase" /> <el-slider v-model="sizeForm.pieInnerRadius" show-input :show-input-controls="false" input-size="mini" :min="0" :max="100" @change="changeBarSizeCase" />
</el-form-item> </el-form-item>
@ -58,7 +58,7 @@
<el-slider v-model="sizeForm.pieOuterRadius" show-input :show-input-controls="false" input-size="mini" :min="0" :max="100" @change="changeBarSizeCase" /> <el-slider v-model="sizeForm.pieOuterRadius" show-input :show-input-controls="false" input-size="mini" :min="0" :max="100" @change="changeBarSizeCase" />
</el-form-item> </el-form-item>
<span v-if="chart.type && chart.type.includes('pie-rose')"> <span v-show="chart.type && chart.type.includes('pie-rose')">
<el-form-item :label="$t('chart.rose_type')" class="form-item"> <el-form-item :label="$t('chart.rose_type')" class="form-item">
<el-radio-group v-model="sizeForm.pieRoseType" size="mini" @change="changeBarSizeCase"> <el-radio-group v-model="sizeForm.pieRoseType" size="mini" @change="changeBarSizeCase">
<el-radio-button label="radius">{{ $t('chart.radius_mode') }}</el-radio-button> <el-radio-button label="radius">{{ $t('chart.radius_mode') }}</el-radio-button>
@ -71,13 +71,13 @@
</span> </span>
</el-form> </el-form>
<el-form v-if="chart.type && chart.type.includes('funnel')" ref="sizeFormPie" :model="sizeForm" label-width="80px" size="mini"> <el-form v-show="chart.type && chart.type.includes('funnel')" ref="sizeFormPie" :model="sizeForm" label-width="80px" size="mini">
<el-form-item :label="$t('chart.funnel_width')" class="form-item form-item-slider"> <el-form-item :label="$t('chart.funnel_width')" class="form-item form-item-slider">
<el-slider v-model="sizeForm.funnelWidth" show-input :show-input-controls="false" input-size="mini" :min="0" :max="100" @change="changeBarSizeCase" /> <el-slider v-model="sizeForm.funnelWidth" show-input :show-input-controls="false" input-size="mini" :min="0" :max="100" @change="changeBarSizeCase" />
</el-form-item> </el-form-item>
</el-form> </el-form>
<el-form v-if="chart.type && chart.type.includes('radar')" ref="sizeFormPie" :model="sizeForm" label-width="80px" size="mini"> <el-form v-show="chart.type && chart.type.includes('radar')" ref="sizeFormPie" :model="sizeForm" label-width="80px" size="mini">
<el-form-item :label="$t('chart.shape')" class="form-item"> <el-form-item :label="$t('chart.shape')" class="form-item">
<el-radio-group v-model="sizeForm.radarShape" size="mini" @change="changeBarSizeCase"> <el-radio-group v-model="sizeForm.radarShape" size="mini" @change="changeBarSizeCase">
<el-radio-button label="polygon">{{ $t('chart.polygon') }}</el-radio-button> <el-radio-button label="polygon">{{ $t('chart.polygon') }}</el-radio-button>
@ -86,7 +86,7 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
<el-form v-if="chart.type && chart.type.includes('table')" ref="sizeFormPie" :model="sizeForm" label-width="100px" size="mini"> <el-form v-show="chart.type && chart.type.includes('table')" ref="sizeFormPie" :model="sizeForm" label-width="100px" size="mini">
<el-form-item :label="$t('chart.table_title_fontsize')" class="form-item"> <el-form-item :label="$t('chart.table_title_fontsize')" class="form-item">
<el-select v-model="sizeForm.tableTitleFontSize" :placeholder="$t('chart.table_title_fontsize')" @change="changeBarSizeCase"> <el-select v-model="sizeForm.tableTitleFontSize" :placeholder="$t('chart.table_title_fontsize')" @change="changeBarSizeCase">
<el-option v-for="option in fontSize" :key="option.value" :label="option.name" :value="option.value" /> <el-option v-for="option in fontSize" :key="option.value" :label="option.name" :value="option.value" />

View File

@ -164,7 +164,7 @@ export default {
// console.log(s_table) // console.log(s_table)
let s = '' let s = ''
for (const i in this.table_header_class) { for (const i in this.table_header_class) {
s += i + ':' + this.table_header_class[i] + ';' s += (i === 'fontSize' ? 'font-size' : i) + ':' + this.table_header_class[i] + ';'
} }
s_table.setAttribute('style', s) s_table.setAttribute('style', s)
}, },
@ -176,12 +176,14 @@ export default {
} }
}, },
summaryMethod({ columns, data }) { summaryMethod({ columns, data }) {
const that = this
const means = [] // const means = [] //
columns.forEach((column, columnIndex) => { columns.forEach((column, columnIndex) => {
if (columnIndex === 0) { if (columnIndex === 0) {
means.push('合计') means.push('合计')
} else { } else {
const values = data.map(item => Number((item[column.property] + '').trim() === '' ? 'a' : item[column.property])) if (columnIndex >= that.chart.data.fields.length - that.chart.data.series.length) {
const values = data.map(item => Number(item[column.property]))
// //
if (!values.every(value => isNaN(value))) { if (!values.every(value => isNaN(value))) {
means[columnIndex] = values.reduce((prev, curr) => { means[columnIndex] = values.reduce((prev, curr) => {
@ -196,6 +198,9 @@ export default {
} else { } else {
means[columnIndex] = '' means[columnIndex] = ''
} }
} else {
means[columnIndex] = ''
}
} }
}) })
// () // ()

View File

@ -129,14 +129,14 @@
<el-tab-pane :label="$t('chart.shape_attr')" class="padding-lr"> <el-tab-pane :label="$t('chart.shape_attr')" class="padding-lr">
<color-selector class="attr-selector" :chart="chart" @onColorChange="onColorChange" /> <color-selector class="attr-selector" :chart="chart" @onColorChange="onColorChange" />
<size-selector class="attr-selector" :chart="chart" @onSizeChange="onSizeChange" /> <size-selector class="attr-selector" :chart="chart" @onSizeChange="onSizeChange" />
<label-selector v-if="!view.type.includes('table')" class="attr-selector" :chart="chart" @onLabelChange="onLabelChange" /> <label-selector v-show="!view.type.includes('table')" class="attr-selector" :chart="chart" @onLabelChange="onLabelChange" />
<tooltip-selector v-if="!view.type.includes('table')" class="attr-selector" :chart="chart" @onTooltipChange="onTooltipChange" /> <tooltip-selector v-show="!view.type.includes('table')" class="attr-selector" :chart="chart" @onTooltipChange="onTooltipChange" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane :label="$t('chart.module_style')" class="padding-lr"> <el-tab-pane :label="$t('chart.module_style')" class="padding-lr">
<title-selector class="attr-selector" :chart="chart" @onTextChange="onTextChange" /> <title-selector class="attr-selector" :chart="chart" @onTextChange="onTextChange" />
<legend-selector v-if="!view.type.includes('table')" class="attr-selector" :chart="chart" @onLegendChange="onLegendChange" /> <legend-selector v-show="!view.type.includes('table')" class="attr-selector" :chart="chart" @onLegendChange="onLegendChange" />
<x-axis-selector v-if="view.type.includes('bar') || view.type.includes('line')" class="attr-selector" :chart="chart" @onChangeXAxisForm="onChangeXAxisForm" /> <x-axis-selector v-show="view.type.includes('bar') || view.type.includes('line')" class="attr-selector" :chart="chart" @onChangeXAxisForm="onChangeXAxisForm" />
<y-axis-selector v-if="view.type.includes('bar') || view.type.includes('line')" class="attr-selector" :chart="chart" @onChangeYAxisForm="onChangeYAxisForm" /> <y-axis-selector v-show="view.type.includes('bar') || view.type.includes('line')" class="attr-selector" :chart="chart" @onChangeYAxisForm="onChangeYAxisForm" />
<background-color-selector class="attr-selector" :chart="chart" @onChangeBackgroundForm="onChangeBackgroundForm" /> <background-color-selector class="attr-selector" :chart="chart" @onChangeBackgroundForm="onChangeBackgroundForm" />
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>

View File

@ -1,6 +1,5 @@
<template> <template>
<el-col> <el-row style="display: flex;flex-direction: column;height: 100%">
<el-row>
<el-row style="height: 26px;"> <el-row style="height: 26px;">
<span style="line-height: 26px;"> <span style="line-height: 26px;">
{{ $t('dataset.add_db_table') }} {{ $t('dataset.add_db_table') }}
@ -44,7 +43,7 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
</el-row> </el-row>
<el-row style="overflow: auto;height: 60vh;"> <el-col style="overflow-y: auto;">
<el-checkbox-group v-model="checkTableList" size="small"> <el-checkbox-group v-model="checkTableList" size="small">
<el-checkbox <el-checkbox
v-for="t in tableData" v-for="t in tableData"
@ -53,9 +52,8 @@
:label="t" :label="t"
/> />
</el-checkbox-group> </el-checkbox-group>
</el-row>
</el-row>
</el-col> </el-col>
</el-row>
</template> </template>
<script> <script>

View File

@ -58,7 +58,7 @@ export default {
this.resetData() this.resetData()
if (this.table.id) { if (this.table.id) {
this.table.row = 10 this.table.row = 10
post('/dataset/table/getPreviewData', this.table).then(response => { post('/dataset/table/getPreviewData/1/10', this.table).then(response => {
this.fields = response.data.fields this.fields = response.data.fields
this.data = response.data.data this.data = response.data.data
const datas = this.data const datas = this.data

View File

@ -34,6 +34,32 @@
</template> </template>
</ux-table-column> </ux-table-column>
</ux-grid> </ux-grid>
<el-row style="margin-top: 4px;">
<span class="table-count">
<span v-if="page.total <= currentPage.show">
{{ $t('dataset.preview_total') }}
<span class="span-number">{{ page.total }}</span>
{{ $t('dataset.preview_item') }}
</span>
<span v-if="page.total > currentPage.show">
{{ $t('dataset.preview_show') }}
<span class="span-number">{{ currentPage.show }}</span>
{{ $t('dataset.preview_item') }}
{{ $t('dataset.preview_total') }}
<span class="span-number">{{ page.total }}</span>
{{ $t('dataset.preview_item') }}
</span>
</span>
<el-pagination
:current-page="currentPage.page"
:page-sizes="[100]"
:page-size="currentPage.pageSize"
:pager-count="5"
layout="sizes, prev, pager, next"
:total="currentPage.show"
@current-change="pageChange"
/>
</el-row>
</el-col> </el-col>
</template> </template>
@ -56,11 +82,20 @@ export default {
form: { form: {
type: Object, type: Object,
required: true required: true
},
page: {
type: Object,
required: false
} }
}, },
data() { data() {
return { return {
height: 500 height: 500,
currentPage: {
page: 1,
pageSize: 100,
show: parseInt(this.form.row)
}
} }
}, },
computed: { computed: {
@ -69,21 +104,46 @@ export default {
data() { data() {
const datas = this.data const datas = this.data
this.$refs.plxTable.reloadData(datas) this.$refs.plxTable.reloadData(datas)
},
page() {
if (this.page.total < parseInt(this.form.row)) {
this.currentPage.show = this.page.total
} else {
this.currentPage.show = parseInt(this.form.row)
}
} }
}, },
mounted() { mounted() {
window.onresize = () => { this.init()
return (() => {
this.height = window.innerHeight / 2
})()
}
this.height = window.innerHeight / 2
},
activated() {
}, },
methods: { methods: {
init() {
this.calHeight()
},
calHeight() {
const that = this
setTimeout(function() {
const currentHeight = document.documentElement.clientHeight
that.height = currentHeight - 56 - 30 - 26 - 25 - 55 - 38 - 28 - 10
}, 10)
},
reSearch() { reSearch() {
this.$emit('reSearch', this.form) if (!this.form.row || this.form.row === '' || this.form.row.length > 8 || isNaN(Number(this.form.row)) || String(this.form.row).includes('.')) {
this.$message({
message: this.$t('dataset.pls_input_less_9'),
type: 'error',
showClose: true
})
return
}
this.currentPage.show = parseInt(this.form.row)
this.currentPage.page = 1
this.$emit('reSearch', { form: this.form, page: this.currentPage })
},
pageChange(val) {
this.currentPage.page = val
// console.log(this.currentPage)
this.$emit('reSearch', { form: this.form, page: this.currentPage })
} }
} }
} }
@ -93,4 +153,19 @@ export default {
.row-style>>>.el-form-item__label{ .row-style>>>.el-form-item__label{
font-size: 12px; font-size: 12px;
} }
.row-style>>>.el-form-item--mini.el-form-item{
margin-bottom: 10px;
}
.el-pagination{
float: right;
}
span{
font-size: 14px;
}
.span-number{
color: #f18126;
}
.table-count{
color: #606266;
}
</style> </style>

View File

@ -464,9 +464,11 @@ export default {
}) })
}, },
handleSizeChange(val) { handleSizeChange(val) {
this.page.pageSize = val
this.listTaskLog() this.listTaskLog()
}, },
handleCurrentChange(val) { handleCurrentChange(val) {
this.page.currentPage = val
this.listTaskLog() this.listTaskLog()
}, },
resetTaskForm() { resetTaskForm() {

View File

@ -1,8 +1,6 @@
<template> <template>
<el-col> <el-row style="height: 100%;overflow-y: hidden;width: 100%;">
<el-row>
<el-row style="height: 26px;"> <el-row style="height: 26px;">
<span v-show="false">{{ tableId }}</span>
<el-popover <el-popover
placement="right-start" placement="right-start"
width="400" width="400"
@ -31,7 +29,7 @@
<el-tabs v-model="tabActive"> <el-tabs v-model="tabActive">
<el-tab-pane :label="$t('dataset.data_preview')" name="dataPreview"> <el-tab-pane :label="$t('dataset.data_preview')" name="dataPreview">
<tab-data-preview :table="table" :fields="fields" :data="data" :form="tableViewRowForm" @reSearch="reSearch" /> <tab-data-preview :table="table" :fields="fields" :data="data" :page="page" :form="tableViewRowForm" @reSearch="reSearch" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane :label="$t('dataset.join_view')" name="joinView"> <el-tab-pane :label="$t('dataset.join_view')" name="joinView">
关联视图 TODO 关联视图 TODO
@ -42,7 +40,7 @@
</el-tabs> </el-tabs>
<el-dialog :title="table.name" :visible.sync="editField" :fullscreen="true" :show-close="false" class="dialog-css"> <el-dialog :title="table.name" :visible.sync="editField" :fullscreen="true" :show-close="false" class="dialog-css">
<el-table :data="tableFields" size="mini" max-height="600px"> <el-table :data="tableFields" size="mini" :max-height="maxHeight">
<el-table-column property="type" :label="$t('dataset.field_type')" width="100"> <el-table-column property="type" :label="$t('dataset.field_type')" width="100">
<template slot-scope="scope"> <template slot-scope="scope">
<span v-if="scope.row.deType === 0"> <span v-if="scope.row.deType === 0">
@ -83,11 +81,10 @@
<!-- <chart-edit/>--> <!-- <chart-edit/>-->
<!-- </el-dialog>--> <!-- </el-dialog>-->
</el-row> </el-row>
</el-col>
</template> </template>
<script> <script>
import { getTable, getPreviewData, fieldList, batchEdit } from '@/api/dataset/dataset' import { getTable, post, fieldList, batchEdit } from '@/api/dataset/dataset'
import TabDataPreview from './TabDataPreview' import TabDataPreview from './TabDataPreview'
import UpdateInfo from './UpdateInfo' import UpdateInfo from './UpdateInfo'
import DatasetChartDetail from '../common/DatasetChartDetail' import DatasetChartDetail from '../common/DatasetChartDetail'
@ -95,6 +92,12 @@ import DatasetChartDetail from '../common/DatasetChartDetail'
export default { export default {
name: 'ViewTable', name: 'ViewTable',
components: { DatasetChartDetail, UpdateInfo, TabDataPreview }, components: { DatasetChartDetail, UpdateInfo, TabDataPreview },
props: {
param: {
type: String,
required: true
}
},
data() { data() {
return { return {
createViewDialog: false, createViewDialog: false,
@ -104,23 +107,34 @@ export default {
}, },
fields: [], fields: [],
data: [], data: [],
page: {
page: 1,
pageSize: 100,
show: 1000
},
tabActive: 'dataPreview', tabActive: 'dataPreview',
tableFields: [], tableFields: [],
tableViewRowForm: { tableViewRowForm: {
row: 1000 row: 1000
}, },
tabStatus: false tabStatus: false,
maxHeight: 'auto'
} }
}, },
computed: { // computed: {
tableId() { // tableId() {
this.initTable(this.$store.state.dataset.table) // this.initTable(this.$store.state.dataset.table)
return this.$store.state.dataset.table // return this.$store.state.dataset.table
// }
// },
watch: {
'param': function() {
this.initTable(this.param)
} }
}, },
watch: {},
mounted() { mounted() {
this.initTable(this.$store.state.dataset.table) this.maxHeight = (document.documentElement.clientHeight - 45 - 78) + 'px'
this.initTable(this.param)
}, },
methods: { methods: {
initTable(id) { initTable(id) {
@ -132,17 +146,18 @@ export default {
this.data = [] this.data = []
getTable(id).then(response => { getTable(id).then(response => {
this.table = response.data this.table = response.data
this.initPreviewData() this.initPreviewData(this.page)
}) })
} }
}, },
initPreviewData() { initPreviewData(page) {
if (this.table.id) { if (this.table.id) {
this.table.row = this.tableViewRowForm.row this.table.row = this.tableViewRowForm.row
getPreviewData(this.table).then(response => { post('/dataset/table/getPreviewData/' + page.page + '/' + page.pageSize, this.table).then(response => {
this.fields = response.data.fields this.fields = response.data.fields
this.data = response.data.data this.data = response.data.data
this.page = response.data.page
}) })
} }
}, },
@ -182,8 +197,8 @@ export default {
}, },
reSearch(val) { reSearch(val) {
this.tableViewRowForm = val this.tableViewRowForm = val.form
this.initPreviewData() this.initPreviewData(val.page)
}, },
showTab() { showTab() {
@ -215,6 +230,6 @@ export default {
padding: 10px 20px; padding: 10px 20px;
} }
.dialog-css >>> .el-dialog__footer { .dialog-css >>> .el-dialog__footer {
padding-top: 30px; padding-top: 10px;
} }
</style> </style>

View File

@ -204,7 +204,7 @@
</span> </span>
<el-dropdown-menu slot="dropdown"> <el-dropdown-menu slot="dropdown">
<el-dropdown-item icon="el-icon-edit-outline" :command="beforeClickMore('editTable',data,node)"> <el-dropdown-item icon="el-icon-edit-outline" :command="beforeClickMore('editTable',data,node)">
{{ $t('dataset.edit') }} {{ $t('dataset.rename') }}
</el-dropdown-item> </el-dropdown-item>
<!-- <el-dropdown-item icon="el-icon-right" :command="beforeClickMore('move',data,node)">--> <!-- <el-dropdown-item icon="el-icon-right" :command="beforeClickMore('move',data,node)">-->
<!-- {{$t('dataset.move_to')}}--> <!-- {{$t('dataset.move_to')}}-->
@ -523,10 +523,6 @@ export default {
back() { back() {
this.sceneMode = false this.sceneMode = false
// const route = this.$store.state.permission.currentRoutes
// console.log(route)
// this.$router.push('/dataset/index')
this.$store.dispatch('dataset/setSceneData', null)
this.$emit('switchComponent', { name: '' }) this.$emit('switchComponent', { name: '' })
}, },
@ -559,16 +555,7 @@ export default {
}, },
sceneClick(data, node) { sceneClick(data, node) {
// console.log(data); this.$emit('switchComponent', { name: 'ViewTable', param: data.id })
this.$store.dispatch('dataset/setTable', null)
this.$store.dispatch('dataset/setTable', data.id)
// this.$router.push({
// name: 'table',
// params: {
// table: data
// }
// })
this.$emit('switchComponent', { name: 'ViewTable' })
}, },
refresh() { refresh() {

View File

@ -3,14 +3,14 @@
<complex-table <complex-table
:data="data" :data="data"
:columns="columns" :columns="columns"
:buttons="buttons"
:header="header"
:search-config="searchConfig" :search-config="searchConfig"
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
@select="select" @select="select"
@search="search" @search="search"
> >
<template #buttons>
<template #toolbar>
<fu-table-button v-permission="['datasource:add']" icon="el-icon-circle-plus-outline" :label="$t('datasource.create')" @click="create" /> <fu-table-button v-permission="['datasource:add']" icon="el-icon-circle-plus-outline" :label="$t('datasource.create')" @click="create" />
</template> </template>
@ -154,7 +154,7 @@ export default {
} }
} }
}, },
activated() { mounted() {
this.search() this.search()
}, },
methods: { methods: {
@ -199,7 +199,7 @@ export default {
this.$success(this.$t('commons.save_success')) this.$success(this.$t('commons.save_success'))
this.search() this.search()
this.dialogVisible = false this.dialogVisible = false
}); })
} else { } else {
return false return false
} }

View File

@ -18,12 +18,11 @@
> --> > -->
<tree-table <tree-table
:columns="columns" :columns="columns"
:buttons="buttons"
:header="header"
:search-config="searchConfig" :search-config="searchConfig"
@search="search" @search="search"
> >
<template #buttons> <template #toolbar>
<fu-table-button v-permission="['dept:add']" icon="el-icon-circle-plus-outline" :label="$t('organization.create')" @click="create" /> <fu-table-button v-permission="['dept:add']" icon="el-icon-circle-plus-outline" :label="$t('organization.create')" @click="create" />
</template> </template>
<el-table <el-table
@ -86,7 +85,7 @@
</el-form-item> </el-form-item>
<el-form-item label="顶级组织" prop="top"> <el-form-item label="顶级组织" prop="top">
<el-radio-group v-model="form.top" style="width: 140px"> <el-radio-group v-model="form.top" style="width: 140px" @change="topChange">
<el-radio :label="true"></el-radio> <el-radio :label="true"></el-radio>
<el-radio :label="false"></el-radio> <el-radio :label="false"></el-radio>
</el-radio-group> </el-radio-group>
@ -199,7 +198,7 @@ export default {
isLazy: true isLazy: true
} }
}, },
activated() { mounted() {
this.form = Object.assign({}, this.defaultForm) this.form = Object.assign({}, this.defaultForm)
this.search() this.search()
}, },
@ -507,6 +506,10 @@ export default {
} }
}) })
return roots return roots
},
topChange(value) {
// console.log(value)
!value && (this.depts = null)
} }
} }

View File

@ -2,12 +2,11 @@
<layout-content v-loading="$store.getters.loadingMap[$store.getters.currentPath]"> <layout-content v-loading="$store.getters.loadingMap[$store.getters.currentPath]">
<tree-table <tree-table
:columns="columns" :columns="columns"
:buttons="buttons"
:header="header"
:search-config="searchConfig" :search-config="searchConfig"
@search="initTableData" @search="initTableData"
> >
<template v-permission="['menu:add']" #buttons> <template #toolbar>
<fu-table-button v-permission="['menu:add']" icon="el-icon-circle-plus-outline" :label="$t('menu.create')" @click="create" /> <fu-table-button v-permission="['menu:add']" icon="el-icon-circle-plus-outline" :label="$t('menu.create')" @click="create" />
</template> </template>
@ -173,7 +172,7 @@ export default {
} }
], ],
searchConfig: { searchConfig: {
useQuickSearch: false, useQuickSearch: true,
useComplexSearch: false, useComplexSearch: false,
quickPlaceholder: '按姓名搜索', quickPlaceholder: '按姓名搜索',
components: [ components: [
@ -195,7 +194,7 @@ export default {
} }
}, },
activated() { mounted() {
this.form = Object.assign({}, this.defaultForm) this.form = Object.assign({}, this.defaultForm)
this.initTableData() this.initTableData()
}, },

View File

@ -7,14 +7,13 @@
highlight-current-row highlight-current-row
:data="tableData" :data="tableData"
:columns="columns" :columns="columns"
:buttons="buttons"
:header="header"
:search-config="searchConfig" :search-config="searchConfig"
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
@search="search" @search="search"
@row-click="rowClick" @row-click="rowClick"
> >
<template #buttons> <template #toolbar>
<fu-table-button icon="el-icon-circle-plus-outline" :label="$t('role.add')" @click="create" /> <fu-table-button icon="el-icon-circle-plus-outline" :label="$t('role.add')" @click="create" />
</template> </template>
@ -107,7 +106,8 @@ export default {
rule: { rule: {
name: [ name: [
{ required: true, message: '请输入名称', trigger: 'blur' } { required: true, message: '请输入名称', trigger: 'blur' }
] ],
code: [{ required: true, message: '请输入代码', trigger: 'blur' }]
}, },
currentRow: null, currentRow: null,
permission: { permission: {
@ -145,7 +145,7 @@ export default {
watch: { watch: {
currentRow: 'currentRowChange' currentRow: 'currentRowChange'
}, },
activated() { mounted() {
this.search() this.search()
}, },
methods: { methods: {

View File

@ -0,0 +1,262 @@
<template>
<layout-content :header="formType=='add' ? $t('user.create') : $t('user.modify')" back-name="用户管理">
<el-form ref="createUserForm" :model="form" :rules="rule" size="small" label-width="auto" label-position="right">
<el-form-item label="用户名" prop="username">
<el-input v-model="form.username" />
</el-form-item>
<el-form-item label="电话" prop="phone">
<el-input v-model="form.phone" />
</el-form-item>
<el-form-item label="昵称" prop="nickName">
<el-input v-model="form.nickName" />
</el-form-item>
<el-form-item label="邮箱" prop="email">
<el-input v-model="form.email" />
</el-form-item>
<el-form-item label="性别">
<el-radio-group v-model="form.gender" style="width: 178px">
<el-radio label="男"></el-radio>
<el-radio label="女"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="状态">
<el-radio-group v-model="form.enabled" style="width: 140px">
<el-radio :label="1">启用</el-radio>
<el-radio :label="0">停用</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="部门" prop="dept">
<treeselect
v-model="form.deptId"
:options="depts"
:load-options="loadDepts"
placeholder="选择部门"
/>
</el-form-item>
<el-form-item label="角色" prop="roleIds">
<el-select
v-model="form.roleIds"
style="width: 100%"
multiple
placeholder="请选择"
@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>
<el-button type="primary" @click="save">保存</el-button>
<el-button @click="reset">重置</el-button>
</el-form-item>
</el-form>
</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/role'
import { addUser, editUser } from '@/api/system/user'
export default {
components: { LayoutContent, Treeselect },
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'
}
],
roleIds: [{ required: true, message: this.$t('user.input_roles'), trigger: 'change' }]
},
defaultForm: { id: null, username: null, nickName: null, gender: '男', email: null, enabled: 1, deptId: null, phone: null, roleIds: [] },
depts: null,
roles: [],
roleDatas: [],
userRoles: [],
formType: 'add'
}
},
created() {
if (this.$router.currentRoute.params && this.$router.currentRoute.params.id) {
const row = this.$router.currentRoute.params
this.edit(row)
} else {
this.create()
}
this.initRoles()
},
methods: {
create() {
this.depts = null
this.formType = 'add'
this.form = Object.assign({}, this.defaultForm)
console.log(this.form)
},
edit(row) {
this.depts = null
this.formType = 'modify'
this.dialogVisible = true
this.form = Object.assign({}, row)
if (this.form.deptId === 0) {
this.form.deptId = null
}
this.initDeptTree()
},
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
}
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.$refs.createUserForm.resetFields()
},
save() {
this.$refs.createUserForm.validate(valid => {
if (valid) {
const method = this.formType === 'add' ? addUser : editUser
method(this.form).then(res => {
this.$success(this.$t('commons.save_success'))
this.backToList()
})
} else {
return false
}
})
},
backToList() {
this.$router.push({ name: '用户管理' })
}
}
}
</script>

View File

@ -3,18 +3,16 @@
<complex-table <complex-table
:data="data" :data="data"
:columns="columns" :columns="columns"
:buttons="buttons"
:header="header"
:search-config="searchConfig" :search-config="searchConfig"
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
@select="select" @select="select"
@search="search" @search="search"
> >
<template #buttons> <template #toolbar>
<fu-table-button v-permission="['user:add']" icon="el-icon-circle-plus-outline" :label="$t('user.create')" @click="create" /> <fu-table-button v-permission="['user:add']" icon="el-icon-circle-plus-outline" :label="$t('user.create')" @click="create" />
</template> </template>
<!-- <el-table-column type="selection" fix /> -->
<el-table-column prop="username" label="ID" width="80" /> <el-table-column prop="username" label="ID" width="80" />
<el-table-column prop="nickName" :label="$t('commons.name')" width="140" /> <el-table-column prop="nickName" :label="$t('commons.name')" width="140" />
<el-table-column prop="gender" label="性别" width="50" /> <el-table-column prop="gender" label="性别" width="50" />
@ -109,7 +107,6 @@
</div> </div>
</el-dialog> </el-dialog>
<!--Changing user password in system settings-->
<el-dialog <el-dialog
:close-on-click-modal="false" :close-on-click-modal="false"
:title="$t('member.edit_password')" :title="$t('member.edit_password')"
@ -145,9 +142,7 @@
<script> <script>
import LayoutContent from '@/components/business/LayoutContent' import LayoutContent from '@/components/business/LayoutContent'
import ComplexTable from '@/components/business/complex-table' import ComplexTable from '@/components/business/complex-table'
// import conditionTable from '@/components/business/condition-table'
// import CustomCondition from './CustomCondtion'
// import { GridButton } from '@/components/GridButton'
import { checkPermission } from '@/utils/permission' import { checkPermission } from '@/utils/permission'
import { formatCondition } from '@/utils/index' import { formatCondition } from '@/utils/index'
import { PHONE_REGEX } from '@/utils/validate' import { PHONE_REGEX } from '@/utils/validate'
@ -285,7 +280,7 @@ export default {
} }
} }
}, },
activated() { mounted() {
// this.form = Object.assign({}, this.defaultForm); // this.form = Object.assign({}, this.defaultForm);
this.allRoles() this.allRoles()
this.search() this.search()
@ -306,23 +301,28 @@ export default {
this.paginationConfig.total = response.data.itemCount this.paginationConfig.total = response.data.itemCount
}) })
}, },
create() { create() {
this.depts = null this.$router.push({ name: '用户表单' })
this.formType = 'add'
this.form = Object.assign({}, this.defaultForm)
this.dialogVisible = true
}, },
// create() {
// this.depts = null
// this.formType = 'add'
// this.form = Object.assign({}, this.defaultForm)
// this.dialogVisible = true
// },
edit(row) { edit(row) {
this.depts = null this.$router.push({ name: '用户表单', params: row })
this.formType = 'modify'
this.dialogVisible = true
this.form = Object.assign({}, row)
if (this.form.deptId === 0) {
this.form.deptId = null
}
this.initDeptTree()
}, },
// edit(row) {
// this.depts = null
// this.formType = 'modify'
// this.dialogVisible = true
// this.form = Object.assign({}, row)
// if (this.form.deptId === 0) {
// this.form.deptId = null
// }
// this.initDeptTree()
// },
editPassword(row) { editPassword(row) {
this.editPasswordVisible = true this.editPasswordVisible = true
const tempForm = Object.assign({}, row) const tempForm = Object.assign({}, row)