提交 1bdc6454 authored 作者: taojinlong's avatar taojinlong

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

...@@ -3,6 +3,8 @@ package io.dataease.controller.sys; ...@@ -3,6 +3,8 @@ package io.dataease.controller.sys;
import com.github.pagehelper.Page; import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageHelper;
import io.dataease.auth.api.dto.CurrentUserDto;
import io.dataease.commons.utils.AuthUtils;
import io.dataease.commons.utils.PageUtils; import io.dataease.commons.utils.PageUtils;
import io.dataease.commons.utils.Pager; import io.dataease.commons.utils.Pager;
import io.dataease.controller.sys.base.BaseGridRequest; import io.dataease.controller.sys.base.BaseGridRequest;
...@@ -73,4 +75,18 @@ public class SysUserController { ...@@ -73,4 +75,18 @@ public class SysUserController {
public void adminUpdatePwd(@RequestBody SysUserPwdRequest request){ public void adminUpdatePwd(@RequestBody SysUserPwdRequest request){
sysUserService.adminUpdatePwd(request); sysUserService.adminUpdatePwd(request);
} }
@ApiOperation("个人信息")
@PostMapping("/personInfo")
public CurrentUserDto personInfo() {
CurrentUserDto user = AuthUtils.getUser();
return user;
}
@ApiOperation("更新个人信息")
@PostMapping("/updatePersonInfo")
public void updatePersonInfo(@RequestBody SysUserCreateRequest request){
sysUserService.updatePersonInfo(request);
}
} }
...@@ -36,4 +36,6 @@ public class ChartViewFieldDTO implements Serializable { ...@@ -36,4 +36,6 @@ public class ChartViewFieldDTO implements Serializable {
private String sort; private String sort;
private List<ChartViewFieldFilterDTO> filter; private List<ChartViewFieldFilterDTO> filter;
private Integer deExtractType;
} }
...@@ -516,8 +516,9 @@ public class DataSetTableService { ...@@ -516,8 +516,9 @@ public class DataSetTableService {
datasetTableField.setDeType(transFieldType(filed.getFieldType())); datasetTableField.setDeType(transFieldType(filed.getFieldType()));
datasetTableField.setDeExtractType(transFieldType(filed.getFieldType())); datasetTableField.setDeExtractType(transFieldType(filed.getFieldType()));
} else { } else {
datasetTableField.setDeType(transFieldType(ds.getType(), filed.getFieldType())); Integer fieldType = transFieldType(ds.getType(), filed.getFieldType());
datasetTableField.setDeExtractType(transFieldType(ds.getType(), filed.getFieldType())); datasetTableField.setDeType(fieldType == 4 ? 2 : fieldType);
datasetTableField.setDeExtractType(fieldType);
} }
datasetTableField.setSize(filed.getFieldSize()); datasetTableField.setSize(filed.getFieldSize());
datasetTableField.setChecked(true); datasetTableField.setChecked(true);
...@@ -555,10 +556,19 @@ public class DataSetTableService { ...@@ -555,10 +556,19 @@ public class DataSetTableService {
public String createQuerySQL(String type, String table, List<DatasetTableField> fields) { public String createQuerySQL(String type, String table, List<DatasetTableField> fields) {
String[] array = fields.stream().map(f -> { String[] array = fields.stream().map(f -> {
StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder = new StringBuilder();
if (f.getDeType() == 1) { // 如果原始类型为时间
stringBuilder.append("FROM_UNIXTIME(cast(").append(f.getDataeaseName()).append(" as decimal(20,0))/1000,'%Y-%m-%d %H:%i:%S') as ").append(f.getDataeaseName()); if (f.getDeExtractType() == 1) {
if (f.getDeType() == 2 || f.getDeType() == 3) {
stringBuilder.append("unix_timestamp(").append(f.getDataeaseName()).append(")*1000 as ").append(f.getDataeaseName());
} else {
stringBuilder.append(f.getDataeaseName());
}
} else { } else {
stringBuilder.append(f.getDataeaseName()); if (f.getDeType() == 1) {
stringBuilder.append("FROM_UNIXTIME(cast(").append(f.getDataeaseName()).append(" as decimal(20,0))/1000,'%Y-%m-%d %H:%i:%S') as ").append(f.getDataeaseName());
} else {
stringBuilder.append(f.getDataeaseName());
}
} }
return stringBuilder.toString(); return stringBuilder.toString();
}).toArray(String[]::new); }).toArray(String[]::new);
......
package io.dataease.service.sys; package io.dataease.service.sys;
import io.dataease.auth.api.dto.CurrentUserDto;
import io.dataease.base.domain.SysUser; import io.dataease.base.domain.SysUser;
import io.dataease.base.domain.SysUserExample; import io.dataease.base.domain.SysUserExample;
import io.dataease.base.domain.SysUsersRolesExample; import io.dataease.base.domain.SysUsersRolesExample;
...@@ -9,6 +10,7 @@ import io.dataease.base.mapper.SysUsersRolesMapper; ...@@ -9,6 +10,7 @@ import io.dataease.base.mapper.SysUsersRolesMapper;
import io.dataease.base.mapper.ext.ExtSysUserMapper; import io.dataease.base.mapper.ext.ExtSysUserMapper;
import io.dataease.base.mapper.ext.query.GridExample; import io.dataease.base.mapper.ext.query.GridExample;
import io.dataease.commons.constants.AuthConstants; import io.dataease.commons.constants.AuthConstants;
import io.dataease.commons.utils.AuthUtils;
import io.dataease.commons.utils.BeanUtils; import io.dataease.commons.utils.BeanUtils;
import io.dataease.commons.utils.CodingUtil; import io.dataease.commons.utils.CodingUtil;
import io.dataease.controller.sys.base.BaseGridRequest; import io.dataease.controller.sys.base.BaseGridRequest;
...@@ -89,6 +91,22 @@ public class SysUserService { ...@@ -89,6 +91,22 @@ public class SysUserService {
deleteUserRoles(user.getUserId());//先删除用户角色关联 deleteUserRoles(user.getUserId());//先删除用户角色关联
saveUserRoles(user.getUserId(), request.getRoleIds());//再插入角色关联 saveUserRoles(user.getUserId(), request.getRoleIds());//再插入角色关联
return sysUserMapper.updateByPrimaryKey(user); return sysUserMapper.updateByPrimaryKey(user);
}
/**
* 用户修改个人信息
* @param request
* @return
*/
@CacheEvict(value = AuthConstants.USER_CACHE_NAME, key = "'user' + #request.userId")
@Transactional
public int updatePersonInfo(SysUserCreateRequest request){
SysUser user = BeanUtils.copyBean(new SysUser(), request);
long now = System.currentTimeMillis();
user.setUpdateTime(now);
return sysUserMapper.updateByPrimaryKeySelective(user);
} }
...@@ -107,20 +125,16 @@ public class SysUserService { ...@@ -107,20 +125,16 @@ public class SysUserService {
*/ */
@CacheEvict(value = AuthConstants.USER_CACHE_NAME, key = "'user' + #request.userId") @CacheEvict(value = AuthConstants.USER_CACHE_NAME, key = "'user' + #request.userId")
public int updatePwd(SysUserPwdRequest request) { public int updatePwd(SysUserPwdRequest request) {
if (!StringUtils.equals(request.getPassword(), request.getRepeatPassword())){ CurrentUserDto user = AuthUtils.getUser();
throw new RuntimeException("两次密码不一致");
}
SysUser temp = new SysUser();
temp.setUserId(request.getUserId());
SysUser user = findOne(temp);
if (ObjectUtils.isEmpty(user)) { if (ObjectUtils.isEmpty(user)) {
throw new RuntimeException("用户不存在"); throw new RuntimeException("用户不存在");
} }
if (!StringUtils.equals(request.getPassword(), user.getPassword())){ if (!StringUtils.equals(CodingUtil.md5(request.getPassword()), user.getPassword())){
throw new RuntimeException("密码错误"); throw new RuntimeException("密码错误");
} }
SysUser sysUser = new SysUser(); SysUser sysUser = new SysUser();
sysUser.setUserId(request.getUserId()); sysUser.setUserId(user.getUserId());
sysUser.setPassword(CodingUtil.md5(request.getNewPassword())); sysUser.setPassword(CodingUtil.md5(request.getNewPassword()));
return sysUserMapper.updateByPrimaryKeySelective(sysUser); return sysUserMapper.updateByPrimaryKeySelective(sysUser);
} }
......
...@@ -99,6 +99,8 @@ INSERT INTO `sys_menu` VALUES (38, 1, 0, 1, '角色表单', '角色表单', 'sys ...@@ -99,6 +99,8 @@ INSERT INTO `sys_menu` VALUES (38, 1, 0, 1, '角色表单', '角色表单', 'sys
INSERT INTO `sys_menu` VALUES (39, 0, 0, 1, '数据源表单', '数据源表单', 'system/datasource/form', 5, NULL, '/ds-form', b'0', b'0', b'1', NULL, NULL, NULL, NULL, NULL); INSERT INTO `sys_menu` VALUES (39, 0, 0, 1, '数据源表单', '数据源表单', 'system/datasource/form', 5, NULL, '/ds-form', b'0', b'0', b'1', NULL, NULL, NULL, NULL, NULL);
INSERT INTO `sys_menu` VALUES (40, 1, 0, 1, '模板管理', '模板管理', 'panel/template/index', 13, 'dashboard', 'panel/template/index', NULL, b'0', b'0', 'sysparam:read', NULL, NULL, NULL, 1620444227389); INSERT INTO `sys_menu` VALUES (40, 1, 0, 1, '模板管理', '模板管理', 'panel/template/index', 13, 'dashboard', 'panel/template/index', NULL, b'0', b'0', 'sysparam:read', NULL, NULL, NULL, 1620444227389);
INSERT INTO `sys_menu` VALUES (41, 1, 0, 1, '权限管理', '权限管理', 'system/permission/index', 14, 'password', 'system/permission/index', b'0', b'0', b'0', 'sysparam:read', NULL, NULL, NULL, 1620447312657); INSERT INTO `sys_menu` VALUES (41, 1, 0, 1, '权限管理', '权限管理', 'system/permission/index', 14, 'password', 'system/permission/index', b'0', b'0', b'0', 'sysparam:read', NULL, NULL, NULL, 1620447312657);
INSERT INTO `sys_menu` VALUES (50, 0, 0, 1, '个人信息', '个人信息', 'system/user/privateForm', 999, NULL, '/person-info', b'0', b'0', b'1', NULL, NULL, NULL, NULL, NULL);
INSERT INTO `sys_menu` VALUES (51, 0, 0, 1, '重置密码', '重置密码', 'system/user/personPwd', 999, NULL, '/person-pwd', b'0', b'0', b'1', NULL, NULL, NULL, NULL, NULL);
COMMIT; COMMIT;
SET FOREIGN_KEY_CHECKS = 1; SET FOREIGN_KEY_CHECKS = 1;
......
import request from '@/utils/request' import request from '@/utils/request'
const pathMap = { const pathMap = {
userUpdatePwdPath: '/api/user/updatePwd/',
personInfoPath: '/api/user/personInfo/',
piupdatePath: '/api/user/updatePersonInfo/',
queryPath: '/api/user/userGrid/', queryPath: '/api/user/userGrid/',
deletePath: '/api/user/delete/', deletePath: '/api/user/delete/',
createPath: '/api/user/create', createPath: '/api/user/create',
...@@ -55,4 +58,27 @@ export const editStatus = (data) => { ...@@ -55,4 +58,27 @@ export const editStatus = (data) => {
}) })
} }
export default { editPassword, delUser, editUser, addUser, userLists, editStatus } export const persionInfo = () => {
return request({
url: pathMap.personInfoPath,
method: 'post'
})
}
export const updatePerson = (data) => {
return request({
url: pathMap.piupdatePath,
method: 'post',
data
})
}
export const updatePersonPwd = (data) => {
return request({
url: pathMap.userUpdatePwdPath,
method: 'post',
data
})
}
export default { editPassword, delUser, editUser, addUser, userLists, editStatus, persionInfo, updatePerson, updatePersonPwd }
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1620973439943" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="859" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M284.281905 870.936381c-85.162667-74.532571-134.339048-184.58819-134.339048-300.592762 0-215.79581 168.082286-391.168 374.881524-391.168s374.808381 175.37219 374.808381 391.168c0.073143 116.150857-49.371429 226.304-134.924191 300.592762L839.68 975.238095C952.124952 879.420952 1024 733.988571 1024 570.343619 1024 282.160762 800.329143 48.761905 524.166095 48.761905 248.003048 48.761905 24.380952 282.185143 24.380952 570.343619 24.84419 727.405714 92.696381 876.007619 209.334857 975.238095l74.971429-104.301714z" p-id="860"></path><path d="M148.821333 570.343619c0-215.79581 167.375238-391.168 373.321143-391.168 77.141333 0 148.699429 24.746667 208.432762 66.486857L804.571429 140.678095C723.72419 82.651429 626.639238 48.761905 522.142476 48.761905 247.125333 48.761905 24.380952 282.185143 24.380952 570.343619 24.380952 733.379048 95.963429 879.420952 207.945143 975.238095l74.654476-104.301714c-84.821333-74.532571-133.802667-184.58819-133.778286-300.592762z" p-id="861"></path><path d="M569.61219 627.492571c5.022476-7.119238 8.777143-15.11619 11.093334-23.576381L731.428571 268.190476 470.503619 523.873524a80.700952 80.700952 0 0 0-18.285714 18.139428c-23.113143 32.914286-15.408762 79.09181 16.822857 102.64381 32.256 23.576381 77.507048 15.725714 100.62019-17.164191h-0.048762z" p-id="862"></path></svg>
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1620974835472" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="863" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M84.94909 930.182095V70.265905A40.521143 40.521143 0 0 0 44.671756 28.769524 40.521143 40.521143 0 0 0 4.370042 70.290286v901.193143c0 22.869333 17.16419 43.641905 39.936 43.641904h906.044952a42.130286 42.130286 0 0 0 41.155048-42.422857c0-22.869333-18.407619-42.398476-41.155048-42.398476H84.94909v-0.121905z" p-id="864"></path><path d="M44.306042 1019.367619c-24.380952 0-44.30019-21.528381-44.300191-48.030476V70.265905a45.348571 45.348571 0 0 1 12.702477-32.182857A45.543619 45.543619 0 0 1 44.647375 24.380952c12.092952 0.121905 23.771429 5.12 32.109715 13.677715 8.338286 8.582095 12.921905 20.406857 12.678095 32.329143V925.988571h861.037714c25.112381 0 45.519238 20.894476 45.519238 46.762667a46.665143 46.665143 0 0 1-45.397333 46.738286L44.306042 1019.367619z m0.243809-986.282667c-9.581714 0.121905-19.017143 4.096-25.746285 11.068953a36.425143 36.425143 0 0 0-10.191238 26.112v901.217524c0 21.625905 15.920762 39.277714 35.547428 39.277714h906.069334a37.936762 37.936762 0 0 0 36.815238-37.912381c0-21.016381-16.554667-38.058667-36.815238-38.058667H80.60928V70.265905c0.24381-9.703619-3.486476-19.260952-10.191238-26.233905a37.156571 37.156571 0 0 0-25.868191-10.947048zM877.939566 781.897143c-40.521143 0-73.362286-33.206857-73.362286-73.996191C804.57728 666.989714 837.418423 633.904762 877.963947 633.904762c40.521143 0 73.362286 33.084952 73.362285 73.99619 0 40.911238-32.841143 73.99619-73.386666 73.996191zM661.119756 394.630095c-63.146667 0-114.395429-51.736381-114.395428-115.395047 0-63.536762 51.346286-115.273143 114.395428-115.273143 63.049143 0 114.41981 51.736381 114.41981 115.273143 0 63.658667-51.370667 115.395048-114.41981 115.395047z" p-id="865"></path><path d="M479.115947 469.577143c-78.57981 0-142.506667 64.414476-142.506667 143.62819a143.262476 143.262476 0 0 0 142.384762 143.628191 140.921905 140.921905 0 0 0 86.479238-29.574095 143.896381 143.896381 0 0 0 55.905524-114.054096c0.121905-79.238095-63.780571-143.62819-142.262857-143.62819zM195.29728 855.04C154.727375 855.04 121.910613 821.833143 121.910613 781.04381 121.910613 740.132571 154.751756 707.047619 195.29728 707.047619c40.521143 0 73.362286 33.084952 73.362286 73.996191 0 40.911238-32.963048 73.99619-73.386667 73.99619z" p-id="866"></path></svg>
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1621224495563" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7328" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M376.795429 691.2c15.616 0 27.008-10.733714 27.008-27.337143v-46.848h1.316571c20.809143 45.878857 63.451429 74.514286 117.449143 74.514286 88.832 0 147.072-70.619429 147.072-179.620572s-58.569143-179.620571-146.413714-179.620571c-53.028571 0-96 28.964571-116.169143 74.203429h-1.627429v-166.290286c0-17.554286-11.062857-28.946286-27.337143-28.946286-16.274286 0-27.318857 11.373714-27.318857 28.946286v423.68c0 16.914286 10.422857 27.318857 26.020572 27.318857z m490.697142 0.329143c64.091429 0 118.765714-35.145143 137.325715-84.937143 1.938286-5.522286 2.925714-10.733714 2.925714-15.286857 0-13.988571-9.764571-23.753143-23.442286-23.753143-12.361143 0-18.870857 4.882286-26.020571 19.2-17.261714 37.101714-46.537143 57.270857-90.459429 57.270857-63.451429 0-105.106286-50.432-105.106285-131.785143 0-80.694857 41.654857-132.443429 105.106285-132.443428 41.965714 0 72.228571 19.858286 89.782857 57.929143 6.857143 13.659429 13.348571 18.541714 25.398858 18.541714 13.988571 0 23.753143-9.106286 23.753142-23.424 0-3.913143-0.969143-8.777143-2.267428-13.019429-16.274286-49.792-71.917714-87.533714-137.984-87.533714-96.950857 0-160.091429 71.259429-160.091429 180.278857 0 109.659429 63.780571 178.962286 161.078857 178.962286zM116.169143 691.2c49.444571 0 96.310857-27.008 115.84-68.662857h0.969143v42.313143c0.658286 15.926857 11.392 26.678857 26.697143 26.678857 15.597714 0 26.331429-10.733714 26.331428-27.977143v-215.405714c0-70.290286-51.401143-115.529143-133.394286-115.529143-60.854857 0-111.286857 26.697143-130.157714 68.022857-3.584 8.118857-5.851429 15.926857-5.851428 22.765714 0 14.317714 10.404571 23.424 24.722285 23.424 10.093714 0 17.554286-3.584 22.784-12.690285 17.554286-37.412571 45.220571-54.674286 87.204572-54.674286 50.102857 0 79.725714 27.977143 79.725714 73.216v27.337143l-103.808 5.851428C45.531429 491.428571 0 528.201143 0 588.068571 0 650.203429 47.506286 691.2 116.169143 691.2z m394.057143-47.177143c-61.184 0-104.777143-52.388571-104.777143-131.785143 0-79.725714 43.593143-132.114286 104.777143-132.114285 63.104 0 102.802286 51.090286 102.802285 131.785142 0 81.353143-39.68 132.114286-102.820571 132.114286z m-381.037715 1.956572c-43.611429 0-72.905143-23.771429-72.905142-58.898286 0-34.176 27.337143-56.630857 77.769142-60.196572l96.969143-6.180571v33.828571c0 51.419429-45.220571 91.428571-101.851428 91.428572z m700.891429 249.892571a39.168 39.168 0 0 0 39.04-39.058286 39.168 39.168 0 0 0-39.058286-39.04c-21.467429 0-39.04 17.572571-39.04 39.058286 0 21.467429 17.554286 39.04 39.058286 39.04z m154.88 0A39.168 39.168 0 0 0 1024 856.813714c0-21.467429-17.554286-39.04-39.04-39.04-21.485714 0-39.058286 17.572571-39.058286 39.058286 0 21.467429 17.572571 39.04 39.058286 39.04z m-309.76 0a38.948571 38.948571 0 0 0 39.04-39.058286 38.948571 38.948571 0 0 0-39.058286-39.04c-21.467429 0-39.04 17.572571-39.04 39.058286 0 21.467429 17.554286 39.04 39.04 39.04z m-154.898286 0a38.948571 38.948571 0 0 0 39.04-39.058286 38.948571 38.948571 0 0 0-39.04-39.04c-21.485714 0-39.058286 17.572571-39.058285 39.058286 0 21.467429 17.572571 39.04 39.058285 39.04z m-154.88 0a38.948571 38.948571 0 0 0 39.04-39.058286 38.948571 38.948571 0 0 0-39.058285-39.04c-21.467429 0-39.04 17.572571-39.04 39.058286 0 21.467429 17.572571 39.04 39.058285 39.04z m-154.88 0a39.241143 39.241143 0 0 0 39.350857-39.058286 39.222857 39.222857 0 0 0-78.409142 0c0 21.485714 17.554286 39.058286 39.04 39.058286z m-155.227428 0a38.948571 38.948571 0 0 0 39.04-39.058286 38.948571 38.948571 0 0 0-39.04-39.04c-21.467429 0-39.04 17.572571-39.04 39.058286 0 21.467429 17.554286 39.04 39.04 39.04z" p-id="7329"></path></svg>
...@@ -395,7 +395,7 @@ export default { ...@@ -395,7 +395,7 @@ export default {
special_characters_are_not_supported: '不支持特殊字符', special_characters_are_not_supported: '不支持特殊字符',
mobile_number_format_is_incorrect: '手机号码格式不正确', mobile_number_format_is_incorrect: '手机号码格式不正确',
email_format_is_incorrect: '邮箱格式不正确', email_format_is_incorrect: '邮箱格式不正确',
password_format_is_incorrect: '有效密码:8-30位,英文大小写字母+数字+特殊字符(可选)', password_format_is_incorrect: '有效密码:6-30位,英文大小写字母+数字+特殊字符(可选)',
old_password: '旧密码', old_password: '旧密码',
new_password: '新密码', new_password: '新密码',
repeat_password: '确认密码', repeat_password: '确认密码',
...@@ -640,7 +640,20 @@ export default { ...@@ -640,7 +640,20 @@ export default {
table_header_bg: '表头背景', table_header_bg: '表头背景',
table_item_bg: '表格背景', table_item_bg: '表格背景',
table_item_font_color: '字体颜色', table_item_font_color: '字体颜色',
stripe: '斑马纹' stripe: '斑马纹',
start_angle: '起始角度',
end_angle: '结束角度',
style_priority: '样式优先级',
dashboard: '仪表盘',
dimension_color: '维度颜色',
quota_color: '指标颜色',
dimension_font_size: '维度字体大小',
quota_font_size: '指标字体大小',
space_split: '维度/指标间隔',
only_one_quota: '仅支持1个指标',
only_one_result: '仅显示第1个计算结果',
dimension_show: '维度显示',
quota_show: '指标显示'
}, },
dataset: { dataset: {
datalist: '数据集', datalist: '数据集',
......
...@@ -37,9 +37,46 @@ ...@@ -37,9 +37,46 @@
<lang-select class="right-menu-item hover-effect" /> <lang-select class="right-menu-item hover-effect" />
</template> </template>
<el-dropdown class="avatar-container" trigger="click">
<el-dropdown class="top-dropdown">
<span class="el-dropdown-link">
{{ name }}<i class="el-icon-arrow-down el-icon--right" />
</span>
<el-dropdown-menu slot="dropdown">
<router-link to="/person-info/index">
<el-dropdown-item>个人信息</el-dropdown-item>
</router-link>
<router-link to="/person-pwd/index">
<el-dropdown-item>重置密码</el-dropdown-item>
</router-link>
<a href="https://panjiachen.github.io/vue-element-admin-site/#/" target="_blank">
<el-dropdown-item>Docs</el-dropdown-item>
</a>
<a href="https://fit2cloud.com/" target="_blank">
<el-dropdown-item>关于</el-dropdown-item>
</a>
<el-dropdown-item divided @click.native="logout">
<span style="display:block;">退出</span>
</el-dropdown-item>
<!-- <el-dropdown-item>黄金糕</el-dropdown-item>
<el-dropdown-item>狮子头</el-dropdown-item>
<el-dropdown-item>螺蛳粉</el-dropdown-item>
<el-dropdown-item disabled>双皮奶</el-dropdown-item>
<el-dropdown-item divided>蚵仔煎</el-dropdown-item> -->
</el-dropdown-menu>
</el-dropdown>
<!-- <el-dropdown class="avatar-container" trigger="click">
<div class="avatar-wrapper"> <div class="avatar-wrapper">
<img src="@/assets/avatar.jpeg" class="user-avatar"> <div class="de-user-avatar">
<span>
{{ name }}
</span>
</div>
</div> </div>
<el-dropdown-menu slot="dropdown" class="user-dropdown"> <el-dropdown-menu slot="dropdown" class="user-dropdown">
<router-link to="/"> <router-link to="/">
...@@ -55,7 +92,7 @@ ...@@ -55,7 +92,7 @@
<span style="display:block;">Log Out</span> <span style="display:block;">Log Out</span>
</el-dropdown-item> </el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
</el-dropdown> </el-dropdown> -->
</div> </div>
</div> </div>
</template> </template>
...@@ -113,7 +150,8 @@ export default { ...@@ -113,7 +150,8 @@ export default {
}, },
...mapGetters([ ...mapGetters([
'avatar', 'avatar',
'permission_routes' 'permission_routes',
'name'
]) ])
}, },
...@@ -222,5 +260,21 @@ export default { ...@@ -222,5 +260,21 @@ export default {
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.el-dropdown-link {
cursor: pointer;
color: #ffffff;
}
.el-icon-arrow-down {
font-size: 12px;
}
.top-dropdown {
display: inline-block;
padding: 10px 8px;
height: 100%;
font-size: 16px;
color: rgba(255,255,255,.87);
vertical-align: text-bottom;
margin-right: 30px;
}
</style> </style>
...@@ -87,6 +87,14 @@ ...@@ -87,6 +87,14 @@
height: 40px; height: 40px;
border-radius: 10px; border-radius: 10px;
} }
.de-user-avatar {
cursor: pointer;
height: 40px;
border-radius: 10px;
span {
color: #ffffff;
}
}
.el-icon-caret-bottom { .el-icon-caret-bottom {
cursor: pointer; cursor: pointer;
......
...@@ -5,7 +5,9 @@ export const DEFAULT_COLOR_CASE = { ...@@ -5,7 +5,9 @@ export const DEFAULT_COLOR_CASE = {
tableHeaderBgColor: '#4e81bb', tableHeaderBgColor: '#4e81bb',
tableItemBgColor: '#c6d9f0', tableItemBgColor: '#c6d9f0',
tableFontColor: '#000000', tableFontColor: '#000000',
tableStripe: true tableStripe: true,
dimensionColor: '#000000',
quotaColor: '#000000'
} }
export const DEFAULT_SIZE = { export const DEFAULT_SIZE = {
barDefault: true, barDefault: true,
...@@ -24,14 +26,24 @@ export const DEFAULT_SIZE = { ...@@ -24,14 +26,24 @@ export const DEFAULT_SIZE = {
funnelWidth: 80, funnelWidth: 80,
radarShape: 'polygon', radarShape: 'polygon',
tableTitleFontSize: 12, tableTitleFontSize: 12,
tableItemFontSize: 12 tableItemFontSize: 12,
gaugeMin: 0,
gaugeMax: 100,
gaugeStartAngle: 225,
gaugeEndAngle: -45,
dimensionFontSize: 18,
quotaFontSize: 18,
spaceSplit: 10,
dimensionShow: true,
quotaShow: true
} }
export const DEFAULT_LABEL = { export const DEFAULT_LABEL = {
show: false, show: false,
position: 'top', position: 'top',
color: '#909399', color: '#909399',
fontSize: '10', fontSize: '10',
formatter: '{c}' formatter: '{c}',
gaugeFormatter: '{value}'
} }
export const DEFAULT_TOOLTIP = { export const DEFAULT_TOOLTIP = {
show: true, show: true,
...@@ -297,3 +309,39 @@ export const BASE_RADAR = { ...@@ -297,3 +309,39 @@ export const BASE_RADAR = {
data: [] data: []
}] }]
} }
export const BASE_GAUGE = {
title: {
text: ''
},
// grid: {
// containLabel: true
// },
tooltip: {},
legend: {
show: true,
type: 'scroll',
itemWidth: 10,
itemHeight: 10,
icon: 'rect'
},
series: [
{
name: '',
type: 'gauge',
startAngle: 225,
endAngle: -45,
min: 0,
max: 100,
progress: {
show: true
},
detail: {
show: true,
valueAnimation: true,
formatter: '{value}'
},
data: []
}
]
}
import { componentStyle } from '../common/common'
import { hexColorToRGBA } from '@/views/chart/chart/util'
export function baseGaugeOption(chart_option, chart) {
// 处理shape attr
let customAttr = {}
if (chart.customAttr) {
customAttr = JSON.parse(chart.customAttr)
if (customAttr.color) {
chart_option.color = customAttr.color.colors
}
// tooltip
if (customAttr.tooltip) {
const tooltip = JSON.parse(JSON.stringify(customAttr.tooltip))
const reg = new RegExp('\n', 'g')
tooltip.formatter = tooltip.formatter.replace(reg, '<br/>')
chart_option.tooltip = tooltip
}
}
// 处理data
if (chart.data) {
chart_option.title.text = chart.title
if (chart.data.series.length > 0) {
chart_option.series[0].name = chart.data.series[0].name
// size
if (customAttr.size) {
chart_option.series[0].min = customAttr.size.gaugeMin
chart_option.series[0].max = customAttr.size.gaugeMax
chart_option.series[0].startAngle = customAttr.size.gaugeStartAngle
chart_option.series[0].endAngle = customAttr.size.gaugeEndAngle
}
// detail
if (customAttr.label) {
const label = JSON.parse(JSON.stringify(customAttr.label))
chart_option.series[0].detail.show = label.show
chart_option.series[0].detail.fontSize = label.fontSize
chart_option.series[0].detail.color = label.color
chart_option.series[0].detail.formatter = label.gaugeFormatter
}
chart_option.series[0].type = 'gauge'
// color
chart_option.series[0].itemStyle = {
color: hexColorToRGBA(customAttr.color.colors[0], customAttr.color.alpha)
}
// data只取第一个
const y = {
name: chart.data.x[0],
value: chart.data.series[0].data[0]
}
chart_option.series[0].data.push(y)
}
}
// console.log(chart_option);
componentStyle(chart_option, chart)
return chart_option
}
...@@ -36,7 +36,9 @@ export function baseLineOption(chart_option, chart) { ...@@ -36,7 +36,9 @@ export function baseLineOption(chart_option, chart) {
type: customAttr.size.lineType type: customAttr.size.lineType
} }
y.smooth = customAttr.size.lineSmooth y.smooth = customAttr.size.lineSmooth
customAttr.size.lineArea ? y.areaStyle = { opacity: 0.6 } : { opacity: 0 } y.areaStyle = {
opacity: customAttr.size.lineArea ? 0.6 : 0
}
} }
// label // label
if (customAttr.label) { if (customAttr.label) {
......
...@@ -5,12 +5,13 @@ ...@@ -5,12 +5,13 @@
</template> </template>
<script> <script>
import { BASE_BAR, BASE_LINE, HORIZONTAL_BAR, BASE_PIE, BASE_FUNNEL, BASE_RADAR } from '../chart/chart' import { BASE_BAR, BASE_LINE, HORIZONTAL_BAR, BASE_PIE, BASE_FUNNEL, BASE_RADAR, BASE_GAUGE } from '../chart/chart'
import { baseBarOption, stackBarOption, horizontalBarOption, horizontalStackBarOption } from '../chart/bar/bar' import { baseBarOption, stackBarOption, horizontalBarOption, horizontalStackBarOption } from '../chart/bar/bar'
import { baseLineOption, stackLineOption } from '../chart/line/line' import { baseLineOption, stackLineOption } from '../chart/line/line'
import { basePieOption, rosePieOption } from '../chart/pie/pie' import { basePieOption, rosePieOption } from '../chart/pie/pie'
import { baseFunnelOption } from '../chart/funnel/funnel' import { baseFunnelOption } from '../chart/funnel/funnel'
import { baseRadarOption } from '../chart/radar/radar' import { baseRadarOption } from '../chart/radar/radar'
import { baseGaugeOption } from '../chart/gauge/gauge'
import eventBus from '@/components/canvas/utils/eventBus' import eventBus from '@/components/canvas/utils/eventBus'
import { uuid } from 'vue-uuid' import { uuid } from 'vue-uuid'
...@@ -91,6 +92,8 @@ export default { ...@@ -91,6 +92,8 @@ export default {
chart_option = baseFunnelOption(JSON.parse(JSON.stringify(BASE_FUNNEL)), chart) chart_option = baseFunnelOption(JSON.parse(JSON.stringify(BASE_FUNNEL)), chart)
} else if (chart.type === 'radar') { } else if (chart.type === 'radar') {
chart_option = baseRadarOption(JSON.parse(JSON.stringify(BASE_RADAR)), chart) chart_option = baseRadarOption(JSON.parse(JSON.stringify(BASE_RADAR)), chart)
} else if (chart.type === 'gauge') {
chart_option = baseGaugeOption(JSON.parse(JSON.stringify(BASE_GAUGE)), chart)
} }
this.myEcharts(chart_option) this.myEcharts(chart_option)
}, },
......
<template>
<div ref="tableContainer" :style="bg_class">
<p v-show="title_show" ref="title" :style="title_class">{{ chart.title }}</p>
<div
v-if="chart.data && chart.data.x && chart.data.x.length > 0 && chart.data.series && chart.data.series.length > 0 && chart.data.series[0].data && chart.data.series[0].data.length > 0"
id="label-content"
:style="content_class"
>
<p v-if="dimensionShow" :style="label_class">
{{ chart.data.x[0] }}
</p>
<span v-if="quotaShow" :style="label_space">
<p v-for="item in chart.data.series" :key="item.name" :style="label_content_class">
{{ item.data[0] }}
</p>
</span>
</div>
</div>
</template>
<script>
import { hexColorToRGBA } from '../../chart/util'
export default {
name: 'LabelNormal',
props: {
chart: {
type: Object,
required: true
},
filter: {
type: Object,
required: false,
default: function() {
return {}
}
}
},
data() {
return {
height: 'auto',
splitHeight: '10px',
dimensionShow: true,
quotaShow: true,
title_class: {
margin: '0 0',
width: '100%',
fontSize: '18px',
color: '#303133',
textAlign: 'left',
fontStyle: 'normal'
},
content_class: {
display: 'flex',
flex: 1,
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
height: 'auto'
},
label_class: {
margin: 0
},
label_content_class: {
margin: 0
},
label_space: {
marginTop: '10px',
textAlign: 'center'
},
bg_class: {
background: hexColorToRGBA('#ffffff', 0)
},
title_show: true
}
},
watch: {
chart() {
this.init()
this.calcHeight()
}
},
mounted() {
this.init()
this.calcHeight()
},
methods: {
init() {
const that = this
this.initStyle()
window.onresize = function() {
that.calcHeight()
}
},
calcHeight() {
const that = this
setTimeout(function() {
// const currentHeight = document.documentElement.clientHeight
// const tableMaxHeight = currentHeight - 56 - 40 - 84 - that.$refs.title.offsetHeight - 20
const currentHeight = that.$refs.tableContainer.offsetHeight
const contentHeight = currentHeight - that.$refs.title.offsetHeight
that.height = contentHeight + 'px'
that.content_class.height = that.height
}, 10)
},
initStyle() {
if (this.chart.customAttr) {
const customAttr = JSON.parse(this.chart.customAttr)
if (customAttr.color) {
this.label_class.color = customAttr.color.dimensionColor
this.label_content_class.color = customAttr.color.quotaColor
}
if (customAttr.size) {
this.dimensionShow = customAttr.size.dimensionShow
this.quotaShow = customAttr.size.quotaShow
this.label_class.fontSize = customAttr.size.dimensionFontSize + 'px'
this.label_content_class.fontSize = customAttr.size.quotaFontSize + 'px'
if (!this.dimensionShow) {
this.label_space.marginTop = '0px'
} else {
this.label_space.marginTop = customAttr.size.spaceSplit + 'px'
}
}
}
if (this.chart.customStyle) {
const customStyle = JSON.parse(this.chart.customStyle)
if (customStyle.text) {
this.title_show = customStyle.text.show
this.title_class.fontSize = customStyle.text.fontSize + 'px'
this.title_class.color = customStyle.text.color
this.title_class.textAlign = customStyle.text.hPosition
this.title_class.fontStyle = customStyle.text.isItalic ? 'italic' : 'normal'
}
if (customStyle.background) {
this.bg_class.background = hexColorToRGBA(customStyle.background.color, customStyle.background.alpha)
}
}
}
}
}
</script>
<style scoped>
.table-class>>>.body--wrapper{
background: rgba(1,1,1,0);
}
</style>
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,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">
<div v-if="sourceType==='view' || sourceType==='panelEchart'"> <div v-if="sourceType==='view' || sourceType==='panelEchart'">
<el-form-item v-show="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') && !chart.type.includes('text')" :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,6 +19,13 @@ ...@@ -19,6 +19,13 @@
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item v-show="(chart.type && chart.type.includes('text')) || sourceType==='panelTable'" :label="$t('chart.dimension_color')" class="form-item">
<colorPicker v-model="colorForm.dimensionColor" style="margin-top: 6px;cursor: pointer;z-index: 1004;border: solid 1px black" @change="changeColorCase" />
</el-form-item>
<el-form-item v-show="(chart.type && chart.type.includes('text')) || sourceType==='panelTable'" :label="$t('chart.quota_color')" class="form-item">
<colorPicker v-model="colorForm.quotaColor" style="margin-top: 6px;cursor: pointer;z-index: 1003;border: solid 1px black" @change="changeColorCase" />
</el-form-item>
</div> </div>
<div v-if="sourceType==='view' || sourceType==='panelTable'"> <div v-if="sourceType==='view' || sourceType==='panelTable'">
<el-form-item v-show="(chart.type && chart.type.includes('table')) || sourceType==='panelTable'" :label="$t('chart.table_header_bg')" class="form-item"> <el-form-item v-show="(chart.type && chart.type.includes('table')) || sourceType==='panelTable'" :label="$t('chart.table_header_bg')" class="form-item">
...@@ -35,7 +42,7 @@ ...@@ -35,7 +42,7 @@
</el-form-item> </el-form-item>
</div> </div>
<el-form-item :label="$t('chart.not_alpha')" class="form-item form-item-slider"> <el-form-item v-show="chart.type && !chart.type.includes('text')" :label="$t('chart.not_alpha')" class="form-item form-item-slider">
<el-slider v-model="colorForm.alpha" show-input :show-input-controls="false" input-size="mini" @change="changeColorCase" /> <el-slider v-model="colorForm.alpha" show-input :show-input-controls="false" input-size="mini" @change="changeColorCase" />
</el-form-item> </el-form-item>
</el-form> </el-form>
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
trigger="click" trigger="click"
> >
<el-col> <el-col>
<el-form ref="labelForm" :model="labelForm" label-width="80px" size="mini"> <el-form v-show="chart.type && !chart.type.includes('gauge')" ref="labelForm" :model="labelForm" label-width="80px" size="mini">
<el-form-item :label="$t('chart.show')" class="form-item"> <el-form-item :label="$t('chart.show')" class="form-item">
<el-checkbox v-model="labelForm.show" @change="changeLabelAttr">{{ $t('chart.show') }}</el-checkbox> <el-checkbox v-model="labelForm.show" @change="changeLabelAttr">{{ $t('chart.show') }}</el-checkbox>
</el-form-item> </el-form-item>
...@@ -43,6 +43,28 @@ ...@@ -43,6 +43,28 @@
<el-input v-model="labelForm.formatter" type="textarea" :autosize="{ minRows: 4, maxRows: 4}" @blur="changeLabelAttr" /> <el-input v-model="labelForm.formatter" type="textarea" :autosize="{ minRows: 4, maxRows: 4}" @blur="changeLabelAttr" />
</el-form-item> </el-form-item>
</el-form> </el-form>
<el-form v-show="chart.type && chart.type.includes('gauge')" ref="labelForm" :model="labelForm" label-width="80px" size="mini">
<el-form-item :label="$t('chart.show')" class="form-item">
<el-checkbox v-model="labelForm.show" @change="changeLabelAttr">{{ $t('chart.show') }}</el-checkbox>
</el-form-item>
<el-form-item :label="$t('chart.text_fontsize')" class="form-item">
<el-select v-model="labelForm.fontSize" :placeholder="$t('chart.text_fontsize')" size="mini" @change="changeLabelAttr">
<el-option v-for="option in fontSize" :key="option.value" :label="option.name" :value="option.value" />
</el-select>
</el-form-item>
<el-form-item :label="$t('chart.text_color')" class="form-item">
<colorPicker v-model="labelForm.color" style="margin-top: 6px;cursor: pointer;z-index: 999;border: solid 1px black" @change="changeLabelAttr" />
</el-form-item>
<el-form-item class="form-item">
<span slot="label">
<span class="span-box">
<span>{{ $t('chart.content_formatter') }}</span>
</span>
</span>
<el-input v-model="labelForm.gaugeFormatter" type="textarea" :autosize="{ minRows: 4, maxRows: 4}" @blur="changeLabelAttr" />
</el-form-item>
</el-form>
</el-col> </el-col>
<el-button slot="reference" size="mini" class="shape-item">{{ $t('chart.label') }}<i class="el-icon-setting el-icon--right" /></el-button> <el-button slot="reference" size="mini" class="shape-item">{{ $t('chart.label') }}<i class="el-icon-setting el-icon--right" /></el-button>
......
...@@ -98,6 +98,43 @@ ...@@ -98,6 +98,43 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-form> </el-form>
<el-form v-show="chart.type && chart.type.includes('gauge')" ref="sizeFormGauge" :model="sizeForm" label-width="100px" size="mini">
<el-form-item :label="$t('chart.min')" class="form-item form-item-slider">
<el-input-number v-model="sizeForm.gaugeMin" size="mini" @change="changeBarSizeCase" />
</el-form-item>
<el-form-item :label="$t('chart.max')" class="form-item form-item-slider">
<el-input-number v-model="sizeForm.gaugeMax" size="mini" @change="changeBarSizeCase" />
</el-form-item>
<el-form-item :label="$t('chart.start_angle')" class="form-item form-item-slider">
<el-slider v-model="sizeForm.gaugeStartAngle" show-input :show-input-controls="false" input-size="mini" :min="-360" :max="360" @change="changeBarSizeCase" />
</el-form-item>
<el-form-item :label="$t('chart.end_angle')" class="form-item form-item-slider">
<el-slider v-model="sizeForm.gaugeEndAngle" show-input :show-input-controls="false" input-size="mini" :min="-360" :max="360" @change="changeBarSizeCase" />
</el-form-item>
</el-form>
<el-form v-show="chart.type && chart.type.includes('text')" ref="sizeFormPie" :model="sizeForm" label-width="100px" size="mini">
<el-form-item :label="$t('chart.dimension_show')" class="form-item">
<el-checkbox v-model="sizeForm.dimensionShow" @change="changeBarSizeCase">{{ $t('chart.show') }}</el-checkbox>
</el-form-item>
<el-form-item :label="$t('chart.dimension_font_size')" class="form-item">
<el-select v-model="sizeForm.dimensionFontSize" :placeholder="$t('chart.dimension_font_size')" @change="changeBarSizeCase">
<el-option v-for="option in fontSize" :key="option.value" :label="option.name" :value="option.value" />
</el-select>
</el-form-item>
<el-form-item :label="$t('chart.quota_show')" class="form-item">
<el-checkbox v-model="sizeForm.quotaShow" @change="changeBarSizeCase">{{ $t('chart.show') }}</el-checkbox>
</el-form-item>
<el-form-item :label="$t('chart.quota_font_size')" class="form-item">
<el-select v-model="sizeForm.quotaFontSize" :placeholder="$t('chart.quota_font_size')" @change="changeBarSizeCase">
<el-option v-for="option in fontSize" :key="option.value" :label="option.name" :value="option.value" />
</el-select>
</el-form-item>
<el-form-item :label="$t('chart.space_split')" class="form-item">
<el-input-number v-model="sizeForm.spaceSplit" size="mini" @change="changeBarSizeCase" />
</el-form-item>
</el-form>
</el-col> </el-col>
<el-button slot="reference" size="mini" class="shape-item">{{ $t('chart.size') }}<i class="el-icon-setting el-icon--right" /></el-button> <el-button slot="reference" size="mini" class="shape-item">{{ $t('chart.size') }}<i class="el-icon-setting el-icon--right" /></el-button>
......
<template> <template>
<div :style="bg_class"> <div ref="tableContainer" :style="bg_class">
<p v-show="title_show" ref="title" :style="title_class">{{ chart.title }}</p> <p v-show="title_show" ref="title" :style="title_class">{{ chart.title }}</p>
<ux-grid <ux-grid
ref="plxTable" ref="plxTable"
...@@ -112,8 +112,10 @@ export default { ...@@ -112,8 +112,10 @@ export default {
calcHeight() { calcHeight() {
const that = this const that = this
setTimeout(function() { setTimeout(function() {
const currentHeight = document.documentElement.clientHeight // const currentHeight = document.documentElement.clientHeight
const tableMaxHeight = currentHeight - 56 - 40 - 84 - that.$refs.title.offsetHeight - 20 // const tableMaxHeight = currentHeight - 56 - 40 - 84 - that.$refs.title.offsetHeight - 20
const currentHeight = that.$refs.tableContainer.offsetHeight
const tableMaxHeight = currentHeight - that.$refs.title.offsetHeight
let tableHeight let tableHeight
if (that.chart.data) { if (that.chart.data) {
tableHeight = (that.chart.data.tableRow.length + 2) * 36 tableHeight = (that.chart.data.tableRow.length + 2) * 36
......
...@@ -89,34 +89,35 @@ ...@@ -89,34 +89,35 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
<div style="height: 30%;overflow:auto" class="padding-lr"> <div style="height: 25%;overflow:auto" class="padding-lr">
<span>{{ $t('chart.chart_type') }}</span> <span>{{ $t('chart.chart_type') }}</span>
<el-row> <el-row>
<div class="chart-type"> <div class="chart-type">
<!--TODO 这里要替换好看点的图标,UI标签可以重新定义--> <!--这里要替换好看点的图标,UI标签可以重新定义-->
<el-radio-group <el-radio-group
v-model="view.type" v-model="view.type"
style="width: 100%" style="width: 100%"
@change="save(false)" @change="save(true)"
> >
<div style="width: 100%;display: flex;display: -webkit-flex;justify-content: space-between;flex-direction: row;flex-wrap: wrap;"> <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>
<el-radio value="text" label="text"><svg-icon icon-class="text" class="chart-icon" /></el-radio>
<el-radio value="bar" label="bar"><svg-icon icon-class="bar" class="chart-icon" /></el-radio> <el-radio value="bar" label="bar"><svg-icon icon-class="bar" class="chart-icon" /></el-radio>
<el-radio value="bar-stack" label="bar-stack"><svg-icon icon-class="bar-stack" class="chart-icon" /></el-radio> <el-radio value="bar-stack" label="bar-stack"><svg-icon icon-class="bar-stack" class="chart-icon" /></el-radio>
<el-radio value="bar-horizontal" label="bar-horizontal"><svg-icon icon-class="bar-horizontal" class="chart-icon" /></el-radio> <el-radio value="bar-horizontal" label="bar-horizontal"><svg-icon icon-class="bar-horizontal" class="chart-icon" /></el-radio>
<el-radio value="bar-stack-horizontal" label="bar-stack-horizontal"><svg-icon icon-class="bar-stack-horizontal" class="chart-icon" /></el-radio>
<el-radio value="line" label="line"><svg-icon icon-class="line" class="chart-icon" /></el-radio>
</div> </div>
<div style="width: 100%;display: flex;display: -webkit-flex;justify-content: space-between;flex-direction: row;flex-wrap: wrap;"> <div style="width: 100%;display: flex;display: -webkit-flex;justify-content: space-between;flex-direction: row;flex-wrap: wrap;">
<el-radio value="bar-stack-horizontal" label="bar-stack-horizontal"><svg-icon icon-class="bar-stack-horizontal" class="chart-icon" /></el-radio>
<el-radio value="line" label="line"><svg-icon icon-class="line" class="chart-icon" /></el-radio>
<el-radio value="line-stack" label="line-stack"><svg-icon icon-class="line-stack" class="chart-icon" /></el-radio> <el-radio value="line-stack" label="line-stack"><svg-icon icon-class="line-stack" class="chart-icon" /></el-radio>
<el-radio value="pie" label="pie"><svg-icon icon-class="pie" class="chart-icon" /></el-radio> <el-radio value="pie" label="pie"><svg-icon icon-class="pie" class="chart-icon" /></el-radio>
<el-radio value="pie-rose" label="pie-rose"><svg-icon icon-class="pie-rose" class="chart-icon" /></el-radio> <el-radio value="pie-rose" label="pie-rose"><svg-icon icon-class="pie-rose" class="chart-icon" /></el-radio>
</div>
<div style="width: 100%;display: flex;display: -webkit-flex;justify-content: space-between;flex-direction: row;flex-wrap: wrap;">
<el-radio value="funnel" label="funnel"><svg-icon icon-class="funnel" class="chart-icon" /></el-radio> <el-radio value="funnel" label="funnel"><svg-icon icon-class="funnel" class="chart-icon" /></el-radio>
<el-radio value="radar" label="radar"><svg-icon icon-class="radar" class="chart-icon" /></el-radio> <el-radio value="radar" label="radar"><svg-icon icon-class="radar" class="chart-icon" /></el-radio>
</div> <el-radio value="gauge" label="gauge"><svg-icon icon-class="gauge" class="chart-icon" /></el-radio>
<div> <!-- <el-radio value="scatter" label="scatter"><svg-icon icon-class="scatter" class="chart-icon" /></el-radio>-->
<el-radio value="table-normal" label="table-normal"><svg-icon icon-class="table-normal" class="chart-icon" /></el-radio>
<el-radio value="" label="" disabled class="disabled-none-cursor"><svg-icon icon-class="" class="chart-icon" /></el-radio>
<el-radio value="" label="" disabled class="disabled-none-cursor"><svg-icon icon-class="" class="chart-icon" /></el-radio>
<el-radio value="" label="" disabled class="disabled-none-cursor"><svg-icon icon-class="" class="chart-icon" /></el-radio> <el-radio value="" label="" disabled class="disabled-none-cursor"><svg-icon icon-class="" class="chart-icon" /></el-radio>
<el-radio value="" label="" disabled class="disabled-none-cursor"><svg-icon icon-class="" class="chart-icon" /></el-radio> <el-radio value="" label="" disabled class="disabled-none-cursor"><svg-icon icon-class="" class="chart-icon" /></el-radio>
</div> </div>
...@@ -124,24 +125,37 @@ ...@@ -124,24 +125,37 @@
</div> </div>
</el-row> </el-row>
</div> </div>
<el-row style="padding: 4px 6px;color: #909399;">
<span>
<span v-show="chart.type && (chart.type.includes('pie') || chart.type.includes('funnel'))">
Tips: {{ $t('chart.only_one_quota') }}
</span>
<span v-show="chart.type && (chart.type.includes('text'))">
Tips: {{ $t('chart.only_one_result') }}
</span>
<span v-show="chart.type && chart.type.includes('gauge')">
Tips: {{ $t('chart.only_one_quota') }},{{ $t('chart.only_one_result') }}
</span>
</span>
</el-row>
<div style="height: 40%;overflow:hidden;border-top: 1px solid #e6e6e6"> <div style="height: 40%;overflow:hidden;border-top: 1px solid #e6e6e6">
<el-row class="padding-lr"> <el-row class="padding-lr">
<span>样式优先级</span> <span>{{ $t('chart.style_priority') }}</span>
<el-radio-group v-model="view.stylePriority" size="mini" @change="save"> <el-radio-group v-model="view.stylePriority" size="mini" @change="save">
<el-radio style="margin-left: 20px" label="view"><span>视图</span></el-radio> <el-radio style="margin-left: 20px" label="view"><span>{{ $t('chart.chart') }}</span></el-radio>
<el-radio label="panel"><span>仪表盘</span></el-radio> <el-radio label="panel"><span>{{ $t('chart.dashboard') }}</span></el-radio>
</el-radio-group> </el-radio-group>
</el-row> </el-row>
<el-tabs type="card" :stretch="true" class="tab-header"> <el-tabs type="card" :stretch="true" class="tab-header">
<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-show="!view.type.includes('table')" class="attr-selector" :chart="chart" @onLabelChange="onLabelChange" /> <label-selector v-show="!view.type.includes('table') && !view.type.includes('text')" class="attr-selector" :chart="chart" @onLabelChange="onLabelChange" />
<tooltip-selector v-show="!view.type.includes('table')" class="attr-selector" :chart="chart" @onTooltipChange="onTooltipChange" /> <tooltip-selector v-show="!view.type.includes('table') && !view.type.includes('text')" 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-show="!view.type.includes('table')" class="attr-selector" :chart="chart" @onLegendChange="onLegendChange" /> <legend-selector v-show="!view.type.includes('table') && !view.type.includes('text')" class="attr-selector" :chart="chart" @onLegendChange="onLegendChange" />
<x-axis-selector v-show="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-show="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" />
...@@ -202,8 +216,9 @@ ...@@ -202,8 +216,9 @@
</el-row> </el-row>
</el-row> </el-row>
<div ref="imageWrapper" style="height: 100%"> <div ref="imageWrapper" style="height: 100%">
<chart-component v-if="chart.type && !chart.type.includes('table')" :chart-id="chart.id" :chart="chart" class="chart-class" /> <chart-component v-if="chart.type && !chart.type.includes('table') && !chart.type.includes('text')" :chart-id="chart.id" :chart="chart" class="chart-class" />
<table-normal v-if="chart.type && chart.type.includes('table')" :chart="chart" class="table-class" /> <table-normal v-if="chart.type && chart.type.includes('table')" :chart="chart" class="table-class" />
<label-normal v-if="chart.type && chart.type.includes('text')" :chart="chart" class="table-class" />
</div> </div>
</el-row> </el-row>
</el-col> </el-col>
...@@ -288,11 +303,12 @@ import BackgroundColorSelector from '../components/component-style/BackgroundCol ...@@ -288,11 +303,12 @@ import BackgroundColorSelector from '../components/component-style/BackgroundCol
import QuotaFilterEditor from '../components/filter/QuotaFilterEditor' import QuotaFilterEditor from '../components/filter/QuotaFilterEditor'
import DimensionFilterEditor from '../components/filter/DimensionFilterEditor' import DimensionFilterEditor from '../components/filter/DimensionFilterEditor'
import TableNormal from '../components/table/TableNormal' import TableNormal from '../components/table/TableNormal'
import LabelNormal from '../components/normal/LabelNormal'
import html2canvas from 'html2canvas' import html2canvas from 'html2canvas'
export default { export default {
name: 'ChartEdit', name: 'ChartEdit',
components: { DimensionFilterEditor, TableNormal, DatasetChartDetail, QuotaFilterEditor, BackgroundColorSelector, FilterItem, XAxisSelector, YAxisSelector, TooltipSelector, LabelSelector, LegendSelector, TitleSelector, SizeSelector, ColorSelector, ChartComponent, QuotaItem, DimensionItem, draggable }, components: { LabelNormal, DimensionFilterEditor, TableNormal, DatasetChartDetail, QuotaFilterEditor, BackgroundColorSelector, FilterItem, XAxisSelector, YAxisSelector, TooltipSelector, LabelSelector, LegendSelector, TitleSelector, SizeSelector, ColorSelector, ChartComponent, QuotaItem, DimensionItem, draggable },
props: { props: {
param: { param: {
type: Object, type: Object,
...@@ -475,7 +491,7 @@ export default { ...@@ -475,7 +491,7 @@ export default {
ele.filter = [] ele.filter = []
} }
}) })
if (view.type.startsWith('pie') || view.type.startsWith('funnel')) { if (view.type.startsWith('pie') || view.type.startsWith('funnel') || view.type.startsWith('gauge')) {
if (view.yaxis.length > 1) { if (view.yaxis.length > 1) {
view.yaxis.splice(1, view.yaxis.length) view.yaxis.splice(1, view.yaxis.length)
} }
......
...@@ -213,8 +213,12 @@ export default { ...@@ -213,8 +213,12 @@ export default {
}, },
cancel() { cancel() {
this.dataReset() // this.dataReset()
this.$emit('switchComponent', { name: '' }) if (this.param.tableId) {
this.$emit('switchComponent', { name: 'ViewTable', param: this.param.tableId })
} else {
this.$emit('switchComponent', { name: '' })
}
}, },
dataReset() { dataReset() {
......
<template>
<layout-content header="修改密码">
<el-form ref="createUserForm" :model="form" :rules="rule" size="small" label-width="auto" label-position="right">
<el-form-item label="原始密码" prop="oldPwd">
<el-input v-model="form.oldPwd" type="password" />
</el-form-item>
<el-form-item label="新密码" prop="newPwd">
<el-input v-model="form.newPwd" type="password" />
</el-form-item>
<el-form-item label="确认密码" prop="repeatPwd">
<el-input v-model="form.repeatPwd" type="password" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="save">保存</el-button>
</el-form-item>
</el-form>
</layout-content>
</template>
<script>
import LayoutContent from '@/components/business/LayoutContent'
import { updatePersonPwd } from '@/api/system/user'
export default {
components: { LayoutContent },
data() {
return {
form: {
},
rule: {
oldPwd: [
{ required: true, message: this.$t('user.input_password'), trigger: 'blur' }
// {
// required: true,
// pattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[^]{6,30}$/,
// message: this.$t('member.password_format_is_incorrect'),
// trigger: 'blur'
// }
],
newPwd: [
{ required: true, message: this.$t('user.input_password'), trigger: 'blur' }
],
repeatPwd: [
{ required: true, message: this.$t('user.input_password'), trigger: 'blur' },
{ required: true, trigger: 'blur', validator: this.repeatValidator }
]
}
}
},
created() {
},
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.$router.push('/panel/index')
})
} else {
return false
}
})
}
}
}
</script>
<template>
<layout-content header="个人信息">
<div>
<el-form ref="createUserForm" :disabled="formType !== 'modify'" :model="form" :rules="rule" size="small" label-width="auto" label-position="right">
<el-form-item label="用户名" prop="username">
<el-input v-model="form.username" disabled />
</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" disabled style="width: 140px">
<el-radio :label="1">启用</el-radio>
<el-radio :label="0">停用</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item disabled label="部门" prop="dept">
<treeselect
v-model="form.deptId"
disabled
:options="depts"
:load-options="loadDepts"
:auto-load-root-options="false"
placeholder="选择部门"
/>
</el-form-item>
<el-form-item label="角色" prop="roleIds">
<el-select
v-model="form.roleIds"
disabled
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 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">确认</el-button>
<el-button v-if="formType!=='modify'" type="primary" @click="edit">编辑</el-button>
</div>
</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/role'
import { updatePerson, persionInfo } 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() {
this.queryPerson()
this.initRoles()
},
methods: {
queryPerson() {
persionInfo().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()
},
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>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论